0

Sorry about the title. I wasnt sure what to name it. If any mods are reading and they understand the question then please rename if needed too.

Say you create a new variable (varOne).

Inside the varOne code, other variables are created as new (varTwo, varThree).

If you call delete on varOne, will varTwo and varThree be deleted, or do you need to delete them AND delete varOne?

maffo
  • 1,393
  • 4
  • 18
  • 35

5 Answers5

2

You only need to delete varTwo and varThree, because when you fall out of varOne's destructor, the delete you used to invoke varOne's destructor will clean up that instance of varOne.

In other words, in the example below, varOne is Foo, varTwo is m_i, and varThre is m_c:

class Foo
{
public:
  Foo() : m_i( new int ), m_c( new char ) { }
  ~Foo() { delete m_i; delete m_c; }
  // don't forget to take care of copy constructor and assignment operator here!!!
private:
  int*  m_i;
  char* m_char;
};

main()
{
  Foo* p = new Foo;
  delete p;
}

Also make sure that when you do this, you follow The Rule of Three or your program will suffer memory problems. (In other words, if you are doing memory allocation in your constructor, be sure you either override or delete the default copy-constructor and assignment operators).

Community
  • 1
  • 1
kfmfe04
  • 14,936
  • 14
  • 74
  • 140
1

You have to delete them and delete varOne seperately, but actually the constructor of varOne should allocate those variables and the destructor should deallocate them if they have to be on the heap for some reason. It would be better to just store them by value and be rid of new and delete for good.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
1

I'm not 100% sure what you mean, but in general, anything that you allocate with new, you have to individually deallocate with delete.

If you mean this in the context of a C++ class, you will need to manually delete varOne and varTwo of the destructor.

Oleksi
  • 12,947
  • 4
  • 56
  • 80
1

Use a smart pointer, and never ever ever delete anything in your own code.

Puppy
  • 144,682
  • 38
  • 256
  • 465
0

I'm not sure how to understand your question, since you don't new a variable (all variables are static, automatic or member variables) but objects (the pointers you get from new will however usually assigned to use used to initialize variables, maybe that's what you meant?). Therefore I'll give a general answer ad hope that what you asked for is included.

First, as a basic rule, every object you allocate with new has to be deallocated explicitly with delete. However, the delete might be hidden in another object, like shared_ptr and scoped_ptr/unique_ptr from boost or C++11, or auto_ptr in earler versions of C++.

If your object contains subobjects, it's usually best to make them direct members, so you don't allocate them with new at all (indeed, that's a general rule in C++: If you don't absolutely have to dynamically allocate, don't). That is, you'd write your class as

class X
{
public:
  // ...
private:
  Type1 subobject1;
  Type2 subobject2:
};

and don't have to mess with new/delete for the sub objects at all. However if you need to dynamically allocate the objects, you also have to delete them, e.g.

class X
{
public:
  X()
  {
    subobject1 = new Type1();
    try
    {
      subobject2 = new Type2();
    }
    catch(...)
    {
      delete subobject1;
    }
  }
  ~X()
  {
    delete subobject2;
    delete subobject1;
  }
  // ...
private:
  X(X const&); // disabled
  X& operator=(X const&); // disabled
  Type1* subobject1;
  Type2* subobject2;
};

Note the rather complicated code in X's constructor to make sure the object is correctly cleaned up even in case of an exception. Also note that you also have to implement copy construction and assignment or disable them by making them private and unimplemented (note that C++11 offers the special syntax = delete to disable them). You can save yourself a lot of the trouble by using a smart pointer (but you still have to take care about copy construction and assignment, at least with the usual smart pointers):

class X
{
public:
  X():
    subobject1(new Type1()),
    subobject2(new Type2())
  {
  }
private:
  X(X const&) = delete; // disabled
  X& operator=(X const&) = delete; // disabled
  std::unique_ptr<Type1> subobject1;
  std::unique_ptr<Type2> subobject2;
};

Here I've used C++11's unique_ptr (and consequently also used C++11 syntax for removing copy constructor and assignment operator). Note that on first impression this code seems to have no delete at all; however those deletes are actually hidden in the destructor of unique_ptr. Also note that now the explicit exception handling in the constructor is no longer needed; since the deleting is done in the destructors of the unique_ptrs, C++'s exception handling rules for constructors automatically take care of this.

celtschk
  • 19,311
  • 3
  • 39
  • 64