Search code examples
c++memoryheap-memorynew-operatordelete-operator

Memory management of class object attributes in C++


I'm sorry if this question was asked before. I searched the internet but couldn't find any clear answer.

Here is the issue :

Let's say I have a public class called Object that has 2 attributes. One is int attr1 and the other one is char * attr2. The constructor is (I have a header file) :

Object::Object(int param1, char * param2) 
{
  attr1=param1; 
  attr2 = new char[strlen(param2)+1]; // I understand that by doing this the values are stored in the heap
  strcpy(attr2, param2); 
}

I understand that in the destructor of the class Object I need to write delete [] attr2.

In another file, main.cpp I create a new object this way :

char * name = "Aname";
Object myObject = new Object(3, name);

From what I've understood, whenever new is used, the value is stored in the heap. Therefore a delete is necessary in order to avoid memory leaks. Here I have used the new operator to create an Object. Therefore myObject is a pointer to an Object stored in the heap. I will need to do this : delete myObject when I will no longer need it.

So this is my question : since the object that myObject points to is stored in the heap, does that mean that all it's attributes are stored in the heap (including attr1 which is simply an int) ? If so, how come I don't have to free it as well (meaning use the operator delete for it in the destructor) ?

Thank you for you help!

Note : english is not my first language, sorry for the mistakes.


Solution

  • The code you showed in your second example will not compile, because

    • myObject is not declared as a pointer

    • in C++11 and later, a non-const char* pointer cannot point to a string literal.

    So you need this instead:

    Object::Object(int param1, const char * param2) 
    {
      attr1 = param1; 
      attr2 = new char[strlen(param2)+1];
      strcpy(attr2, param2); 
    }
    
    const char * name = "Aname";
    Object * myObject = new Object(3, name); // <-- note the * !
    

    That being said, the rest of your comments are correct. Since myObject is being created with new, its data members reside in dynamic memory (ie, the heap), and you must call delete myObject to destroy it and free its memory when you are done using it. And since you are directly allocating memory for attr2 with new[], you need to manually call delete[] attr2 to free it.

    However, you are NOT directly allocating memory for attr1 with new, so you DO NOT need to manually call delete attr1. The memory for attr1 is managed by the compiler and will be released automatically when myObject is destroyed.

    In short, when something is allocated explicitly by a function/operator, it must be deallocated explicitly with a corresponding function/operator, eg:

    • when something is explicitly allocated with the C++ new or new[] operator, it must be explicitly deallocated with the delete or delete[] operator, respectively.

    • if something is explicitly allocated with the C runtime (m|c|re)alloc() funtion, it must be explicitly deallocated with the C runtime free() function.

    • if something is explicitly allocated with the Win32 API (Local|Global)Alloc() or (Local|Global)ReAlloc() function, it must be explicitly deallocated with the Win32 API (Local|Global)Free() function.

    • etc