سؤال

I'm new to this website, and to the programming world. So, please be patient with me :)

I read about the rule of three, and I understood how the Copy Constructor and the Assignment operator work. So I understood that, the default ones, provided by C++, provide a shallow-copy (or memberwise) of the objects.

My question is ... if the class has a member pointer (which points to dynamic allocated memory), the default Assignment Operator, will only copy the address held in the pointer from the original object to the pointer of the object is being assigned to. But won't this create a memory leak? For example, the followind code:

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;
    }

So, in this code, when gc1 is created, gc1.toolHolder holds the address of some dynamic allocated memory of 5 strings. Let's say, address 125. After this, gc2 is created and dynamic allocates memory for 5 strings, and let's say gc2.toolHolder holds the address 135.

The next line of code, calls the default assignment operator, and provides a shallow-copy from every member of gc1 to gc2. This means that now the pointer gc2.toolHolder also holds the address 125, and we no longer can access the memory at address 135. So the default assignment operator, in situations like these, creates memory leaks? ... or I understood something wrong??

Also, another question, in the case of the default Copy Constructor, because it is called only on objects that don't already exist, it means that gc3.toolHolder won't get the chance to allocate new memory, let's say, at address 145? It will just receive the address stored in gc1.toolHolder?

To try to be more specific... what I'm asking is if it's the same case as above, except we just have both pointers gc3.toolHolder and gc1.toolHolder, reference the same address 125, without gc3.toolHolder dynamic allocating new memory of 5 strings.

Long story short, when we instantiate a class that has a pointer member variable which points to dynamic allocated memory, will the default assignment operator cause a memory leak? and the default copy constructor share pointers to the same allocated memory?

Thank you for your time!

هل كانت مفيدة؟

المحلول

The memory leak you have is the lack of a destructor which frees the memory allocated with new in the constructor, you need:

~GCharacter() { delete[] toolHolder; }

If you add this, you will see the second problem you have: The default generated copy-ctor and assignment just copy/assign the pointer, hence when you have a copy and both original and copy go out of scope, they will both try to delete the memory. This double-free is of course the much bigger problem than the memory leak as it will most likely corrupt the memory.

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top