删除std :: map(Visual C ++)

4
我有一个指向使用new分配的地图的指针,我想要删除它。
我认为这张地图是有效的,当我在调试时悬停在它上面时,它显示“pMap:[0]()”...
当我尝试删除这个空地图时,我的应用程序就会退出,并且我会在输出窗口中得到一个“第一次机会异常”,错误代码为0xsomenumber:“所调用的对象已与其客户端断开连接”。
这是什么意思?
谢谢。。
编辑:这里有一些示例代码:
typedef map<const char*, StructA*, StructB> myMap;
typedef vector<myMap *> myMapStack;

StructB有一个重载运算符()

在我的代码的某一部分,一个类的构造函数调用一个名为InitClass()的方法来初始化一个指向myMap的指针:

pMyMap = new myMap; // I also tried this with new myMap()
// this pointer is then pushed onto the a map stack
pMyMapStack.push_back(pMyMap);

在这个类的析构函数中,我会进行后续操作。
pMyMap = pMyMapStack.back();
pMyMapStack.pop_back();

delete pMyMap; // after I step over this line the app quits.. and displays that message

谢谢

编辑:我回退到了一个之前可用的版本,现在它正在正常工作。

可用的代码类似于:

// after the pMyMapStack.pop_back()
int x = pMyMap->size();
if (x >= 0)
    delete pMyMap;

之前我已经将其更改为以下内容:

// after the pMyMapStack.pop_back()
int (x = pMyMap->size();
if (x >= 0){
    pMyMap->clear();
    delete pMyMap;
}

很奇怪.. 代码可能有其他问题,但我还没有找到它在哪里.. 如果我把整个代码都发布出来的话,它太大了(而且我可能会被解雇),所以就让它保持现状吧..

我认为可能是指向一个空映射的指针,我正在尝试清除或删除它,这可能导致了问题..

感谢所有试图帮助我的人... :)


添加代码。分配的样子是什么?删除的样子是什么?具体的std::map<K,V>类型声明是什么? - Pontus Gagge
你能加一些代码示例吗?谷歌上没有明显指向错误的内容。 - pmr
你从来没有向地图中添加任何值吗? - Ton van den Heuvel
@Pontus Gagge:我该如何检查分配的情况?这些结构体没有构造函数.. - krebstar
也许这里并不是问题所在,但我不会在STL容器中使用原始指针。转而使用boost::shared_ptr可能是个好主意(或者干脆不用指针)。 - Rune Aamodt
显示剩余4条评论
6个回答

5

嗯,你的示例代码存在很多问题。当你实例化地图时:<const char*, StructA*, StructB*>,事情开始变得不对劲了。

你为什么要在地图中存储指针而不是值呢?std::map可能会在堆上存储你添加到其中的元素。此外,应该使用std::string代替const char*。然后,没有理由将比较器作为指针传递。

同样,对于你的mapStack(如果需要栈,为什么不使用一个?),只要你不共享对象或使用纯虚基类,就没有使用指针的理由。如果必须使用指针,请尽量不要使用裸指针。

在解决了这些错误之后,就没有理由使用newdelete了。


大多数情况下是一致的,但要挑刺的是:指针不仅在对象共享时有用,而且在使用子类化时也很有用。但由于我们正在讨论结构体,这似乎并不相关。 - Pontus Gagge
抱歉,这整个东西实际上相当庞大和复杂,如果我对事情做出太多改变,我担心会出错。让我看看能否找到更多的信息...谢谢。 - krebstar

1

由于您发布的代码中没有任何可能导致此问题的内容,我在Google上搜索了您的错误字符串,并发现它与COM有关。

这篇文章可能会对您有所帮助: 什么可能导致错误0x80010108(调用的对象已经从其客户端断开连接)?

与问题无关: 我觉得这很有趣:

typedef map<const char*, StructA*, StructB*> myMap;

你的第三个模板参数怎么是一个结构体指针?我原以为它必须是一个普通的类/类型。

1

因为没有代码可用,所以只是猜测。你确定指针指向的是单个地图而不是地图数组吗(如果是地图数组,则需要使用delete [])?


1

在执行 pop_back() 之前,你应该先执行 delete 操作。


从技术上讲是无效的,但这并不重要。即使它不会破坏其他东西,所提出的修复措施也无法消除真正的错误。 - MSalters
我不会说它是无效的,但它也不能解决任何问题。 - CiscoIPPhone
pop_back()调用元素上的析构函数,因此在之后调用delete似乎不是一个好主意。显然,像pmr指出的那样,代码中还有许多其他问题。 - Tim
pop_back()不调用析构函数,因为堆栈包含指向元素而不是元素本身的指针。 - CiscoIPPhone
我的意思是一般而言。是的,在这种情况下,该值是一个指针,因此没有什么需要销毁的,但是内存可能仍然会被重复使用,不是吗?现在中间没有代码,但是也许他只是没有发布它。 - Tim
我不确定包含悬空指针的堆栈是一个更好的想法。这样,在弹出和删除之间,他的指针是有效的,所以我不明白你想说什么。 - CiscoIPPhone

1
你像没有明天一样随意操作指针。最有可能的解释是你通过一个已经被释放(但非空)的指针写入了你的地图结构,从而破坏了它。请查看pmr的答案以获取更多建议。除非必须,否则不要使用指针。在你的代码中,使用地图对象而不是地图指针几乎没有理由。

如果我真的必须使用指针,我能否确保每个已释放的指针都被置空? - krebstar

1

说实话,如果没有真正的代码发布,我们是走不了什么地方的。

可能有101个地方出错了,不仅限于发布的片段。

从所展示的对象插入和删除实现来看,既没有语法错误也没有逻辑错误。 如果源代码很有价值并且可以在这里共享,请尝试创建一个足够简单的虚拟项目来演示问题(如果问题不存在于虚拟项目中,则知道您正在处理错误的方向)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接