【问题标题】:Deleting an std::map (Visual C++)删除 std::map (Visual C++)
【发布时间】:2011-01-22 05:16:23
【问题描述】:

我有一个指向我要删除的地图的指针(这个地图是用新分配的)。

我认为这张地图是有效的,当我在调试时将鼠标悬停在上面时,它会显示pMap: [0]() ..

当我尝试删除这个空地图时,我的应用程序就退出了,我得到了一个

myapp.exe 中 0xsomelocation 的第一次机会异常:0xsomenumber:调用的对象已与其客户端断开连接。

在输出窗口中。这是什么意思?

谢谢..

编辑:这是一些示例代码:

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

StructB 有一个重载的运算符() 编辑: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 类型的声明是什么?
  • 您能添加一些示例代码吗?谷歌没有提出任何明显的错误。
  • 您从不向地图添加任何值?
  • @Pontus Gagge:如何检查分配情况?结构没有构造函数..
  • 我在追你pMyMap = new myMap;

标签: c++ visual-c++ destructor stdmap delete-operator


【解决方案1】:

嗯,您的示例代码存在很多问题。当您将地图实例化为:&lt;const char*, StructA*, StructB*&gt; 时,事情开始出错了 您是否有理由在地图中存储指针而不是值? 无论如何,std::map 很可能会将您添加到其中的元素存储在堆上。你也应该使用std::string 而不是const char*。那么绝对没有理由将比较器作为指针传入。

对于您的mapStack 也是如此(如果您需要一个堆栈,为什么不使用一个?)。只要您不共享对象或使用纯虚拟基类,就没有理由使用指针。如果你必须使用指针,尽量不要使用原始指针。

在您解决了这些错误之后,您应该没有任何理由使用newdelete

【讨论】:

  • 大部分同意,但要挑剔:指针不仅在共享对象时有用,而且在使用子类化时也有用。这似乎不相关,因为我们正在谈论结构。
  • 对不起,这整个事情实际上是相当大和复杂的,我害怕如果我改变太多东西会破坏东西..让我看看我能不能找到更多的东西......谢谢..
【解决方案2】:

老实说,我认为如果没有发布真正的代码,我们将无处可去。

代码出错的地方可能有101处,不限于贴出来的sn-p。

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

【讨论】:

    【解决方案3】:

    只是在黑暗中拍摄,因为没有可用的代码。您确定指针指向单个地图而不是地图数组(在这种情况下您需要使用delete [])?

    【讨论】:

      【解决方案4】:

      您应该在执行 pop_back() 之前执行删除操作。

      【讨论】:

      • 技术上无效,但没关系。即使它不会破坏其他东西,建议的修复也不会消除真正的错误。
      • 我不会说它无效,但它不会解决任何问题。
      • pop_back() 在元素上调用析构函数,所以对我来说之后调用 delete 似乎是个坏主意。正如 pmr 所指出的,显然代码还有许多其他问题。
      • pop_back() 不调用析构函数,因为堆栈包含指向元素的指针,而不是元素本身。
      • 我的意思是一般。是的,在这种情况下,值是一个指针,所以没有什么可以破坏的,但内存仍然可以重用,不是吗?现在中间没有代码,但也许他只是没有发布它。
      【解决方案5】:

      你就像没有明天一样到处乱扔指针。最可能的解释是,您正在通过一个已释放(但非空)的指针写入来破坏您的映射结构。有关更多建议,请参阅 pmr 的答案。除非必须,否则不要使用指针。您的代码几乎没有理由处理映射指针而不是映射对象。

      【讨论】:

      • 说,如果我真的必须使用指针,我可以确保每个释放的指针都是 NULLED 吗?
      【解决方案6】:

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

      这篇文章可以帮助你: What may be the causes of the error 0x80010108 (The object invoked has disconnected from its clients)?

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

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

      您的第三个模板参数如何是结构 pointer?我认为它必须是一个普通的类/类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-02
        • 1970-01-01
        • 2011-04-14
        • 2018-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        相关资源
        最近更新 更多