3

我是这个网站的新手,也是编程世界的新手。所以,请耐心等待我:)

我阅读了三法则,并且了解了 Copy Constructor 和 Assignment 运算符的工作原理。所以我明白,由 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个字符串的记忆。

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

感谢您的时间!

4

1 回答 1

2

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

~GCharacter() { delete[] toolHolder; }

如果你添加这个,你会看到你遇到的第二个问题:默认生成的 copy-ctor 和 assignment 只是复制/分配指针,因此当你有一个副本并且原始和副本都超出范围时,它们都会尝试删除记忆。这种双重释放当然是比内存泄漏更大的问题,因为它很可能会破坏内存。

That said, you want to add your own copy-ctor and assignment operator and implement it correctly. In this case it means to allocate memory for the copy's toolHolder. Generally, read about the Rule of Five for when to implement which set of methods for your class.

于 2013-10-20T21:28:11.853 回答