2

I've this C++ class:

class test{

    char* p;
    SomeClass* someObject;

   test(){
      ...
      p = (char*) malloc(1000);
      someObject = new SomeClass();
      ...
   }

   ~test(){}

}

Do I need to call free(p) or delete someObject explicitly in test destructor in order to free their allocated memory or that memory will free automatically?

Ehsan Khodarahmi
  • 4,390
  • 9
  • 57
  • 81

5 Answers5

8

You need to free all dynamically allocated memory in the destructor. This does not get done automatically.

Your class contains two pointers, and essentially has no control over what these point to. In fact, these could point to objects that you are not allowed to delete, for example:

struct Foo {};
struct Bar {
  Foo* f_;
  Foo(Foo* f) : f(f_) {}
};

int main() {
  Foo f;
  Bas b(&f); // b has a Foo ptr, but should it delete it?
}

So you can see that it doesn't really make sense for pointer data members to be deleted automatically.

As a general rule, if your class manages resources1, then you should take care of copy construction and assignment; that means, you should either disable them if that makes sense for the class, or provide implementation for them because the compiler generated ones would not work. For detail discussion on this topic, see the rule of three, and extensive discussions on stackoverflow:

If you don't follow this rule, then the default copy constructor and assignment operation will make a shallow copy and you will have more than one instance having pointers to the same dynamically allocated objects, which they will all try to delete upon destruction.

You can avoid manually deleting objects created with new by using smart pointers. In your case, where the class obviously owns the dynamically allocated object,you should look at C++11's std::unique_ptr or boost::scoped_ptr

Finally, you can really avoid all memory management problems by avoiding pointers all together, unless you really need to. You could replace your char* by an std::string for example:

class test{

    std::string p;
    SomeClass someObject;
    //test() : someObject() {} // default construction is probably OK...
};

1. That is, it allocates and deallocates memory, or opens and closes network connection, or creates and destroy mutexes and so on.

Community
  • 1
  • 1
juanchopanza
  • 210,243
  • 27
  • 363
  • 452
3

Yes, you have to free anything you malloc and delete everything you new.

You can also avoid that by not storing pointers in your class.

class test{
public:
    std::string   p;
    SomeClass     someObject;
};
juanchopanza
  • 210,243
  • 27
  • 363
  • 452
Bo Persson
  • 86,087
  • 31
  • 138
  • 198
1

Yes, you need. If you don't want, you can use the Smart Pointer

RolandXu
  • 3,098
  • 2
  • 12
  • 20
0

Yes, you need to free them explicitly. Pointer as a data type does not have any destructor. Compiler/execution enviroment does not have any means to guess if pointer points to anything meaningfull or not. Even if the value is meaningfull, it may point to some static object for example. Or it can point to some field of a bigger object. Compiler is not doing any automatic cleanup on pointers.

Kirill Kobelev
  • 9,758
  • 6
  • 24
  • 46
0

The memory is technically leaked if you do not reclaim it when the instance of test is destructed. You could use a smart pointer instead to avoid calling free or delete explicitly in the destructor.

struct Free { void operator () (void *p) const { free(p); } };

class test {
    std::unique_ptr<char, Free> p;
    std::unique_ptr<SomeClass> someObject;
    test () : p(static_cast<char *>(malloc(1000)),
              someObject(new SomeClass)
    { //...
    }
    ~test () {}
};

This uses the destructor of the smart pointer to perform the clean up action for you.

If test were only used as const global instances, then it is less important to implement the cleanup since the memory would not be reclaimed until the execution had ended anyway. But it is good practice to always implement the cleanup, because it would make the code correct now, and test may be used differently in the future.

jxh
  • 64,506
  • 7
  • 96
  • 165