-2

So we have the following code, which illustrates an "Array of pointers" (I think)

main() {
  int *array[3];
  int x = 10, y = 20, z = 30;

  array[0] = &x;
  array[1] = &y;
  array[2] = &z;

  return 0;
}

Now, let's say instead of ints, they are a type of an object class that you have created.

So I want to remove a member from this array (i.e. to call its destructor by means of the delete keyword and have the object destroyed, but having the pointer remain fine.)

If my suspicions are correct, that isn't possible, and the only choice I have is to copy the contents of the array to a new array (except for the one(s) I want to delete) and then delete the previous array (as a whole with all of its elements) while I assign the new one to the pointer array

I would appreciate if someone could confirm or correct my suspicions, specially since the name "Array of pointers" is SO misleading. Thank you.

Ren
  • 4,594
  • 9
  • 33
  • 61
  • Doing it like this, you shouldn't need `delete`, and it'd be UB to try. – chris Oct 24 '12 at 03:01
  • no, deleting the main "array" will only delete the array, the pointers will remain in tact. This is actually something that causes memory leaks in most cases with people who forget that with their array of pointers they need to loop through and delete the memory in each element. (unless you used "delete [] array", that would delete the contents as well) – u8sand Oct 24 '12 at 03:02
  • What are you trying to do that a `std::vector` and `std::vector::erase` won't work? – chris Oct 24 '12 at 03:03
  • @u8sand, If you have a `new[]`ed array of `new`ed pointers, `delete[]`ing the array will not `delete` the pointers. – chris Oct 24 '12 at 03:04
  • My professor won't let me use the STL Vector. Also, I meant like for example only erasing the contents of `array[1]`. In the first case it would be easy, you just assign it zero, but I said, imagine it is an object. How do you deal with that? – Ren Oct 24 '12 at 03:05
  • @u8sand it won't? Now all this sounds more confusing. I thought `delete[]` would delete everything, elements, pointers and the array too... – Ren Oct 24 '12 at 03:08
  • @Yokhen, in that case, you can just `delete array[0]` and NULL it: `array[0] = NULL`. – Eric Z Oct 24 '12 at 03:08
  • 2
    Basic handling of pointers and objects is described by all [standard textbooks](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – jogojapan Oct 24 '12 at 03:08
  • @EricZ wouldn't that cause a memory leak? – Ren Oct 24 '12 at 03:09
  • thank you @jogojapan, I have read plenty, yet still not fully understanding. – Ren Oct 24 '12 at 03:10
  • Well now its just getting confusing on understanding what each of us are talking about lmfao... delete [] array; deletes an array and all of its elements. In the case of an array with pointers, the pointers would be deleted (the 4 bytes taken by a pointer) but not the data pointed to by the pointer. maybe I said something confusing above.. – u8sand Oct 24 '12 at 03:10
  • This whole discussion is why we have memory-managing containers and smart pointers. – chris Oct 24 '12 at 03:11
  • @Yokhen The reason I made that remark is that any answer provided here that properly explains (i) pointers, (ii) stack vs heap allocation, (iii) when to use `delete` and (iv) how arrays fit into this, will be as complex as the corresponding chapter in a text book. There is no 3-lines quick answer that explains all of this. – jogojapan Oct 24 '12 at 03:12

2 Answers2

2

Assuming you have a class Foo

Foo a;

This is an instance of the Foo object. It is allocated on the stack. It will be destructed when they go out of scope, no sooner.

If you want to be able to explicitly destroy your object, allocate it on the heap.

Foo* a = new Foo(); // Allocated - Constructor called.
delete a; // Freed - Destructor called.

A good rule to remember is, for every new there should be a matching delete, no more, no less. In your example you haven't used the new keyword, so there is no place for the delete keyword.

Foo* array[3];

Is an array, on the stack, of Foo object pointers. They do not point to anything, they are uninitialized. This array will be destroyed when it goes out of scope. Keep in mind that it will only destroy the contents, which are pointers, and will not attempt to free anything they point to.

array[0] = new Foo();

The array now holds a pointer to a Foo object on the heap. It also contains 2 pointers that are uninitialized. If you let array go out of scope, you will be leaking memory. To prevent this, you must free your Foo object.

delete array[0];
array[0] = NULL;

It is also good practice to set your uninitialized, or deleted pointers to NULL. This way you can explicitly see that it points to nothing. You can now perform checks like so:

if(array[0])
{
    // We know there is an object here, since it's not NULL.
    delete array[0];
    array[0] = NULL; // Helps prevent trying to free memory more than once.
}
Aesthete
  • 18,622
  • 6
  • 36
  • 45
0

As far as I understand your problem, it won't work for two reasons:

  1. you won't be able to delete such elements (int's or A's) at all as they reside on the stack, not in the heap, they will be deleted automatically when out-of-scope;
  2. deleting or moving an array won't delete its elements as it was already said above.

As for "erasing the contents of array[1]", that can be done via:

array[1] = NULL;

if I understand you correctly.

Artem Shitov
  • 2,889
  • 1
  • 15
  • 8
  • So if the elements reside in the stack, how would I avoid a stack overflow if I am always adding and removing new items? – Ren Oct 24 '12 at 03:17