tags:

views:

3762

answers:

8

So I have a pointer to an array of pointers. If I delete it like this:

delete [] PointerToPointers;

Will that delete all the pointed to pointers as well? If not, do I have to loop over all of the pointers and delete them as well, or is there an easier way to do it? My google-fu doesn't seem to give me any good answers to this question.

(And yeah, I know I need to use a vector. This is one of those "catch up on C++" type assignments in school.)

+1  A: 

I think you're going to have to loop over I'm afraid.

Matt Sheppard
+2  A: 

Pointers are pretty much just memory references and not spiffy little self-cleaning .net objects. Creating proper destructors for each class will make the deletion a little cleaner than massive loops throughout the code.

Jeffrey
+16  A: 

Yes you have to loop over the pointers, deleting individually.

Reason: What if other code had pointers to the objects in your array? The C++ compiler doesn't know if that's true or not, so you have to be explicit.

For an "easier way," two suggestions: (1) Make a subroutine for this purpose so at least you won't have to write the code more than once. (2) Use the "smart pointer" design paradigm where you hold an array of objects with reference-counters, then the objects are deleted when the objects are no longer referenced by any code.

Jason Cohen
+5  A: 

I agree with Jason Cohen though we can be a bit clearer on the reason for needing to delete your pointers with the loop. For every "new" or dynamic memory allocation there needs to be a "delete" a memory de-allocation. Some times the "delete" can be hidden, as with smartpointers but it is still there.

int main()
{
  int *pI = new int;
  int *pArr = new int[10];

so far in the code we have allocated two chunks of dynamic memory. The first is just a general int the second is an array of ints.

  delete pI;
  delete [] pArr;

these delete statements clear the memory that was allocated by the "new"s

  int ppArr = new int *[10];

  for( int indx = 0; indx < 10; ++indx )
  {
    ppArr[indx] = new int;
  }

This bit of code is doing both of the previous allocations. First we are creating space for our int in a dynamic array. We then need to loop through and allocate an int for each spot in the array.

  for( int indx = 0; indx < 10; ++indx )
  {
    delete ppArr[indx];
  }
  delete [] ppArr;

Note the order that I allocated this memory and then that I de-allocated it in the reverse order. This is because if we were to do the delete [] ppArr; first we would loose the array that tells us what our other pointers are. That chunk or memory would be given back to the system and so can no longer be reliably read.

  int a=0;
  int b=1;
  int c=2;

  ppArr = new int *[3];

  ppArr[0] = &a;
  ppArr[1] = &b;
  ppArr[2] = &c;

This I think should be mentioned as well. Just because you are working with pointers does not mean that the memory those pointers point to was dynamically allocated. That is to say just because you have a pointer doesn't mean it necessarily needs to be delete. The array I created here is dynamically allocated but the pointers point to local instances of ints When we delete this we only need to delete the array.

  delete [] ppArr;

  return 0;

}

In the end dynamically allocated memory can be tricky and anyway you can wrap it up safely like in a smart pointer or by using stl containers rather then your own can make your life much more pleasant.

Ray
+3  A: 

See boost pointer container for a container that does the automatic deletion of contained pointers for you, while maintaining a syntax very close to ordinary STL containers.

Greg Rogers
Nice, I didn't know about those!
A: 

I don't know why this was answered so confusingly long.

If you delete the array of pointers, you will free the memory used for an array of usually ints.
a pointer to an object is an integer containing the adress.

You deleted a bunch of adresses, but no objects.

delete does not care about the content of a memory space, it calls a destructor(s) and marks the mem as free.

It does not care that it just deleted a bunch of adresses of objects, it merely sees ints.

That's why you have to cycle through the array first! and call delete on every element, then you can delete the storage of the array itself.

Well, now my answer got somewhat long... .... strange... ;)

Edit: Jason's answer is not wrong, it just fails to hit the spot. Neither the compiler nor anything else in c(++) cares about you deleting stuff that is elsewhere pointed to. You can just do it. Other program parts trying to use the deleted objects will segfault on you. But no one will hinder you. Neither will it be a problem to destroy an array of pointers to objects, when the objects are referenced elsewhere.

AndreasT
"Other program parts trying to use the deleted objects will segfault on you".... segfaulting is probably the best possible outcome, it traps the spot where the problem is. But there are plenty of other possibilities, which won't be noticed until later and might even cause corruption lasting past program exit (if a file write buffer got allocated in the now free memory, for example).
Ben Voigt
A: 

delete ar[]; ar=NULL;

pravinkumar s.m
A: 

Let's take a (pseudocoded) real world example .Imagine that you had a class like this:

class Street
{
    public:
        Street();
        ~Street();
    private:
        int HouseNumbers_[];
}

typedef *Street StreetSign;

If you have an array of street signs, and you delete your array of streetsigns, that doesn't mean that you automatically delete the sreets. They re still there, bricks and mortar, they just don't have those signs pointing to them any more. You have got rid of those specific instances of pointers to the streets.

An array of pointers is (conceptually) a bit like an array of integers, it's an array of numbers representing the memory locations of various objects. It isn't the objects themselves.

If you delete[] the array of pointers, all you have done is delete an array of integers.

RikSaunderson