【问题标题】:C++ - Is my object being deleted twice if I use a map? [duplicate]C++ - 如果我使用地图,我的对象会被删除两次吗? [复制]
【发布时间】:2016-05-05 09:26:13
【问题描述】:

我一直在从事 Qt 项目,但在删除地图中的对象时遇到了问题。我准备了一个简单的 C++ 代码来显示我的问题:

   #include <iostream>
#include <map>
#include <string>

using namespace std;

    class A 
    {
    public:
        int *tab;

        A()
        {
            tab = NULL;
        }
        ~A()
        {
            if (tab != NULL)
            {
                delete[] tab;
            }
        }
    };

        int main()
        {
            map<string, A> mapa;

            string name = "MyArray";

            A *a = new A;
            a->tab = new int[3];
            a->tab[0] = 1;
            a->tab[1] = 2;
            a->tab[2] = 3;

            mapa[name] = *a;

            delete a;


            system("PAUSE");
            return 0;
        }

关闭程序后,我得到: 调试断言失败!

_BLOCK_TYPE_IS_VALID 等等。

我的问题是:为什么会这样?原因可能是在我退出程序后 map 被删除,并且它包含一个在我关闭程序之前被删除的 A 对象 (a)。但是,我传递的是一个值,而不是一个地址,那么有什么问题呢?

该值不是刚刚复制到地图中并保存在某个不同的地址中吗?

【问题讨论】:

  • 我是 OT,但本着向您指出三法则的精神...我建议您阅读 Scott Meyers 的“Effective C++”系列。
  • @n.m.:我已经说过了。在答案部分。您的评论没有添加任何内容...
  • 另见:Rule of FiveRule of Zero
  • @Lightness 是的,你做了,但从你的回答中不清楚 OP 到底应该做什么。太多的建议要遵循。我的评论增加了一些确定性。但如果你坚持,我可以删除它;)

标签: c++ memory-leaks


【解决方案1】:

是的,你是双重删除。

地图复制它们的元素,而你的类型没有复制构造函数。你实际上是在用mapa[name] = *a 自己复制A

成员指针的归属也很不清楚。

遵守三原则。理想情况下完全避免手动动态分配; A 应该有一个 std::vector&lt;int&gt; 代替。

【讨论】:

  • 嗯,正如我所说,我一直在做一个 Qt 项目,没有办法避免动态分配,我只好使用它。好吧,感谢您的回答,所以实际上,如果一个类型没有复制构造函数,则映射将保存一个指向该对象的指针。复制构造函数应该可以解决这个问题,好吧,我很愚蠢:s
  • @MindRoller:如果一个类型没有你编写的复制构造函数,那么它有一个由编译器生成的复制构造函数,它只是复制指针。然后你有两个 As “拥有”同一个指针,并且两者都会在销毁时 delete[] 它。您需要实现深层复制或从析构函数中删除 delete[]。正如我所说,动态分配内存的所有权在您的程序中并不清楚。
  • 好的,谢谢,我会记一辈子的,哈哈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
  • 2021-06-06
相关资源
最近更新 更多