Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper destruction of pointers to objects

I would like to ask a couple of quick questions about the proper destruction of int pointers and vector pointers. First, I have seen people ask in the past about these type of problems, and almost always there are several responses about how using vector pointers , pointers to objects ,etc in C++ is not good standard c++ coding practice, and that you should instantiate a copy of the object. That may be true, but you do not always have control of paradigms that have been layed before your arrival. The paradigm I am required to work in requires initializing pointers to almost everything. A very Java like approach to C++. One of the main reasons we do this is our data sets are so large , stack allocations would be subject to overflows.

My questions:

If I have a pointer to a int32_t array, what is the proper way to destroy it in the destructor?

Note: Our practice is to set any pointer to NULL in the constructor.

I initialize it as a member variable. 
int32_t *myArray_;

When I use it in a method, I would:
this->myArray = new int32_t[50];

To delete it in the method I would call delete on the array:
delete [] this->myArray;

What is the proper call in the destructor?
~MyDestructor(){

    delete this->myArray_;
    or delete [] this->myArray_;

}

I have the same question about vector pointers:

I initialize it as a member variable. 
std::vector<MyObject*> *myVector_;

When I use it in a method, I would:
this->myVector_ = new std::vector<MyObject*>();


//pushback some objects

To delete the vector in the method I would iterate the vector and delete its objects, then    delete the vector;

 for(std::vector<MyObject*>::iterator itr = this->myVector_->begin(); 
 its != this->myVector->end(); ++ itr){

      delete (*itr);

}

delete this->myVector_;


What would be the proper way to clean it up in the destructor?
would I just delete the vector?

delete this->myVector;

or do I need to iterate the entire vector again?

Thanks in advance for any advice.

like image 287
Miek Avatar asked Dec 12 '12 17:12

Miek


People also ask

How do you deconstruct a pointer in C++?

std::vector<MyObject*> *myVector_; When I use it in a method, I would: this->myVector_ = new std::vector<MyObject*>(); //pushback some objects To delete the vector in the method I would iterate the vector and delete its objects, then delete the vector; for(std::vector<MyObject*>::iterator itr = this->myVector_->begin ...

Do pointers need to be deleted?

No. The only exception to that would be if deltaTime was created with new and it was the responsibility of Update to return the memory (unlikely, and a poor design). like you would with any other pointer? Just because something is a pointer does not mean you should call delete .

Does deleting a pointer delete the object?

The only thing that ever gets deleted is the object *test , which is identical to the object *test2 (since the pointers are the same), and so you must only delete it once.


1 Answers

Anything allocated with new should be deallocated with delete.

int* p = new int;
delete p;

Anything allocated with new [] should be deallocated with delete [].

int* p = new int[10];
delete [] p;

Anything dynamically allocated and stored in a vector, needs to be manually deallocated:

std::vector<int*> v;
v.push_back(new int(1));
v.push_back(new int(2));

for(std::vector<int*>::iterator i = v.begin(), e = v.end(); i != e; ++i)
   delete (*i);

If, for some strange reason, you feel it is appropriate to dynamically allocate a vector, the same rules apply.

std::vector<int*>* v = new std::vector<int*>;
v->push_back(new int(1));
v->push_back(new int(2));

for(std::vector<int*>::iterator i = v->begin(), e = v->end(); i != v; ++i)
   delete (*i);

delete v;

But, I would suggest that the reasons to dynamically allocate a std::vector are few and far between.

In C++11, the best way to do this, is with std::unique_ptr:

std::unique_ptr<int> p(new int);
// std::unique_ptr handles clean up for you


std::unique_ptr<int[]> p(new int[10]);
// std::unique_ptr handles clean up for you for arrays too!

If you have a member variable of a class, the same rules apply:

class Foo
{
   Foo()
      : bar_(new int)
      , bar2_(new int[20])
   {
   }

   ~Foo()
   {
      delete [] bar2_;
      delete bar_;
   }

   int* bar_;
   int* bar2_;
};

But even then, it makes more sense to have them as std::unique_ptr, you can even treat them as raw pointers in interfaces when required:

class Foo
{
   Foo()
     : bar_(new int)
     , bar2_(new int[20])
   {
   }

   int* get_bar()
   {
      return bar_.get();
   }

   int* get_bar2()
   {
      return bar2_.get();
   }

   std::unique_ptr<int> bar_;
   std::unique_ptr<int[]> bar2_;
};
like image 109
Chad Avatar answered Oct 04 '22 05:10

Chad