4
int *ip = new int[10];
for (int i = 0; i<10; i++)
    *(ip+i) = i;

myfun(ip);  // assume that myfun takes an argument of
            //   type int* and returns no result

delete [] ip;

The above code is a small segment of a test function that I am trying to use to learn about the stack and the heap.

I am not fully sure what the correct sequence is.

This is what I have thus far:

  • When the pointer ip is created it points to a new int array of size 10 created on the heap due to to the "new" declaration.
  • 0-9 is added to the array from 0-9.
  • The pointer is now passed through to myfun which means that myfun has a pointer that points to the same memory space on the heap.
  • The delete []ip; removes the memory allocated on the heap to the ip pointer. The pointer that got passed through to myFun now points to nothing.
  • Once the function has finished the ip variable is deleted as it is only local to the function.

Would someone be able to clarify if I am correct or not and correct me where I went wrong? Also if I attempted to carry on using ip after that would it just point to nothing ?

trincot
  • 317,000
  • 35
  • 244
  • 286
Softey
  • 1,451
  • 3
  • 21
  • 42
  • 1
    stack variables are not literally deleted, stack top (`esp`) simply goes down. the next called function will move it up again, and so on so forth – mangusta May 18 '15 at 09:27
  • @mangusta Are you saying that when a variable is declared inside a function and the function finishes the variable is just moved down the stack? I thought it was deleted as it went out of scope and couldn't be used. – Softey May 18 '15 at 09:28
  • 2
    Conceptually the variable is *destroyed*, practically this is done by returning the stack pointer to where it was before the function was called. – TartanLlama May 18 '15 at 09:31
  • 4
    *"The pointer that got passed through to myFun now points to nothing."* - that's a bit vague... the pointer will continue to hold the same memory address, but it won't be valid to dereference the pointer until after it's assigned a still-valid pointer value. – Tony Delroy May 18 '15 at 09:31
  • @TonyD so the items at the memory just get cleaned out but the memory is still there and potentially accessible but should be reassigned values before you dereference the pointer? – Softey May 18 '15 at 09:34
  • 1
    "potentially accessible" is a slippery slope. It's best to assume that trying to access that memory will give you nasal demons, even if the data there might be valid. – TartanLlama May 18 '15 at 09:35
  • 2
    Also, `new` allocates memory on the *free-store* rather than the heap, but that is mostly a conceptual difference. – TartanLlama May 18 '15 at 09:36
  • @TartanLlama I appreciate the corrections i'd rather know the nitty gritty points so I can make the ideas abstract in the correct way. – Softey May 18 '15 at 09:38
  • 1
    The items in memory at the address passed to `delete[]` usually sit there until some other dynamic memory allocation (another call to `new` or perhaps `malloc` if they're using the same underlying memory) returns a fully or partially overlapping memory area (or the dynamic memory allocation library itself decides to use that memory for some housekeeping/management information). It is not legal to access it again yourself unless the allocation library happens to give you another pointer to it from another `new` or `malloc`. It's the pointer that should be reassigned before dereferencing. – Tony Delroy May 18 '15 at 09:40
  • As a sidenote: congratulations for getting quite right the concepts that make up 97% of C++ newbie errors. This will definitely pay off. – Marco A. May 18 '15 at 09:46
  • @Softey: [this question's accepted answer](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) seems - from the upvotes - to have either amused or helped a lot of people get their heads around these concepts.... – Tony Delroy May 18 '15 at 09:52
  • @TonyD thank you for the forward and corrections. I will look into it. – Softey May 18 '15 at 09:56

3 Answers3

3

I believe everything is correct, I have the following minor remark regarding the following bullet point;

  • The delete []ip; removes the memory allocated on the heap to the ip pointer. The pointer that got passed through to myFun now points to nothing.

It is not guaranteed that the pointer points to "nothing", in general it is recommended (see clarification in comment below this answer) that after your delete call, you initialize the pointer to NULL, i.e. ip = NULL in order to ensure the pointer points to nothing (instead of pointing to unallocated memory).

Gio
  • 3,242
  • 1
  • 25
  • 53
  • 2
    *"in general it is recommended"* - I'd recommend *not* doing this if the pointer's about to end its lifetime, e.g. because it's in a scope that's about to exit, or it's been `delete`d inside a destructor... in such situations, to set it to NULL would falsely suggest some significance/utility and be needlessly verbose. – Tony Delroy May 18 '15 at 09:48
3

The sequence is correct except one point:

The delete []ip; removes the memory allocated on the heap to the ip pointer. The pointer that got passed through to myFun now points to nothing.

The pointer doesn't point to 'nothing' (i.e. isn't set to nullptr or 0 after freeing the memory). It just points to the same location which is now freed memory (i.e. memory marked as freed by the application and that can no longer be safely accessed). Accessing memory through that pointer would trigger undefined behavior.

One last notice: myfun might take the pointer by value or by reference. There are differences but your sentence would still be valid.

Marco A.
  • 43,032
  • 26
  • 132
  • 246
1

Everything is correct. But beware that calling delete doesn't delete anything but free the memory previously allocated, which means that your pointer contains the address that you mustn't use (dereferencing a free chunk of memory leeads to undefined behavior). The same for your stack variable, the memory associated to your local variable is not destroyed but released, so you mustn't try to use it. stack and heap are just two ways of memory management with two basic same operation (alloc/free).

So technically you can't say that your pointer points to anything, but it points to something that you are not authorized to use.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69