C++ 在浅层复制指针时,默认赋值运算符是否会造成内存泄漏?

C++ 在浅层复制指针时,默认赋值运算符是否会造成内存泄漏?,c++,pointers,operator-overloading,copy-constructor,shallow-copy,C++,Pointers,Operator Overloading,Copy Constructor,Shallow Copy,我不熟悉这个网站,也不熟悉编程世界。所以,请对我耐心点:) 我阅读了关于三的规则,并且理解了复制构造函数和赋值操作符是如何工作的。 所以我明白,默认的C++提供了对象的浅拷贝(或成员)。 我的问题是。。。如果类有一个成员指针(指向动态分配的内存),默认赋值运算符将只将指针中的地址从原始对象复制到要分配的对象的指针。但这不会造成内存泄漏吗? 例如,以下代码: class GCharacter //Game Character { private:

我不熟悉这个网站,也不熟悉编程世界。所以,请对我耐心点:)

我阅读了关于三的规则,并且理解了复制构造函数和赋值操作符是如何工作的。 所以我明白,默认的C++提供了对象的浅拷贝(或成员)。 我的问题是。。。如果类有一个成员指针(指向动态分配的内存),默认赋值运算符将只将指针中的地址从原始对象复制到要分配的对象的指针。但这不会造成内存泄漏吗? 例如,以下代码:

class GCharacter //Game Character
        {
            private:
                std::string name;
                int capacity;   //the capacity of our tool array
                int used;       //the nr of elements that we've actually used in that tool array
                std::string* toolHolder; //string pointer that will be able to reference our ToolArray;

            public:
                static const int DEFAULT_CAPACITY = 5;
            //Constructor 
                GCharacter(std::string n = "John", int cap = DEFAULT_CAPACITY) 
                :name(n), capacity(cap), used(0), toolHolder(new string[cap])
                {
                }
        }

    int main()
    {         GCharacter gc1("BoB", 5); 
              GCharacter gc2("Terry", 5); 
              gc2 = gc1;
              GCharacter gc3 = gc1;

              return 0;
    }
因此,在这段代码中,当gc1被创建时,gc1.toolHolder持有一些动态分配内存的地址,这些内存由5个字符串组成。比如说,地址125。在这之后,gc2被创建,动态地为5个字符串分配内存,假设gc2.toolHolder持有地址135

下一行代码调用默认赋值运算符,并提供从gc1到gc2的每个成员的浅层副本。这意味着现在指针gc2.toolHolder也持有地址125,我们不再能够访问地址135处的内存。因此,在这种情况下,默认赋值运算符会导致内存泄漏。。。或者我理解错了什么

还有一个问题,在默认复制构造函数的情况下,因为它只在不存在的对象上调用,这意味着gc3.toolHolder将没有机会分配新内存,比如在地址145处?它将只接收存储在gc1.toolHolder中的地址

想说得更具体些。。。我想问的是,如果情况与上面相同,除了我们有两个指针gc3.toolHolder和gc1.toolHolder,引用相同的地址125,没有gc3.toolHolder动态分配5个字符串的新内存

长话短说,当我们实例化一个具有指向动态分配内存的指针成员变量的类时,默认赋值运算符是否会导致内存泄漏?默认复制构造函数共享指向同一分配内存的指针


谢谢你抽出时间

内存泄漏是因为缺少析构函数来释放构造函数中分配的
new
内存,您需要:

~GCharacter() { delete[] toolHolder; }
如果添加此项,您将看到第二个问题:默认生成的复制ctor和分配只是复制/分配指针,因此当您有一个副本且原始和副本都超出范围时,它们将同时尝试删除内存。这个双重空闲当然是比内存泄漏更大的问题,因为它很可能会损坏内存


也就是说,您希望添加自己的复制构造函数和赋值操作符,并正确地实现它。在这种情况下,它意味着为副本的
刀架
分配内存。通常,请阅读关于何时为类实现哪一组方法的说明。

长话短说,使用RAII容器,您将不会遇到以下问题:pYes,您将有内存泄漏。Daniel已经给出了一个很好的答案,我在这里只建议您使用program
valgrind
来检查内存泄漏和类似问题。我还建议您阅读关于如何避免担心此问题的;-)好的,明白了。但即使我提供自己的析构函数。。。我脑子里也有同样的问题
gc2=gc1
将导致
gc2.刀架
无法再引用其分配的内存。那不是内存泄漏吗?顺便说一句,我知道在处理动态内存时,最好提供我们自己的复制构造函数和析构函数并分配op。。。但我想先了解默认的赋值运算符是如何工作的。@xPlay Sure,因此您需要一个正确的赋值运算符。但是,通过重用正确的拷贝和交换,您可以降低复杂性和出现错误的机会。看。@DanielFrey谢谢!:)看来在我回到这个话题之前,我必须先研究一下这些页面。