简体   繁体   中英

C++ delete a pointer (free memory)

Consider the following code:

int a = 10;
int * b = &a;
int * c = b;
delete b; // equivalent to delete c;

Am I correct to understand in the last line, delete b and delete c are equivalent, and that both will free the memory space holding a , thus a is no longer accessible?

The behaviour of your program is undefined . You can only use delete on a pointer to memory that you have allocated using new . If you had written

int* b = new int;
*b = 10;
int* c = b;

then you could write either delete b; or delete c; to free your memory. Don't attempt to derefererence either b or c after the delete call though, the behaviour on doing that is also undefined .

If b and c point to the same memory then deleting either of them releases the memory so that assumption is correct. a becoming inaccessible is not correct in this case though as you do not point to dynamically allocated memory and you can only call delete / delete[] on something that was created with new / new[] . Trying to delete / delete[] a pointer that was not allocated with new / new[] is undefined behavior and will generally end in a segmentation fault.

The confusing part is that the answer to your question

Am I correct to understand in the last line, delete b and delete c are equivalent"

Is yes, they're equivalent, and both UB as mentioned everywhere else here.

you should never use delete for variable that allocated on stack, delete is the counterpart of new. hence no delete/free is needed when no new/alloc is used, once you are out of the "scope" of the code ( in this case the program itself ) all memory is considered available.

This particular answer uses a particular implementation of the heap to go into detail about what would happen in your proposed situation; however this matters very little as other versions would still have similar issues close to the argument I provide.

The answer is "no", and it is because of what other people have said. However, I am going to be a bit more precise, because I think you don't actually know what the stack and heap are and so I'm going to take the time to explain that you.

Now first off, everything I'm saying in terms of details about the heap are a "lie". Nobody knows specifically what your compiler does to implement the heap. So I can only give my understanding of a heap instead.

New and delete are actually two functions (if you've heard of operator overloading you'll understand what I mean by this) that accept pointers and modify a data structure in memory known as the heap. It one of four main data structures in a C/C++ program's memory (the heap, the stack, the text, and the static space).

The heap is essentially a linked list but instead of storing data in each node, you cram the data in between them. If you are unfamiliar with a linked list, then in this context it is a two component "array" sitting in raw memory. The second component is the length of the block stored in front of it. The first component is the length of the block before it. In this manner it easy to find a block as it is just a matter of moving down the list searching for a block. Usually (because programs are not even close to being complex enough to need 2^31 bytes allocated within a single block) the leftmost bit is used as a true/false value saying whether the block is free. Hence free and new are just operations upon the list and free simply backs the pointer up by one to look at the node and make appropriate changes. I won't go into more detail because those familiar with doubly linked lists should understand the operations and if you don't understand, there's no point in me trying to teach you something you'll learn in a much grander depth later.

Remember: Your implementations will vary by compiler. This is just an example.

The stack on the other is where your local variables are. It's literally a giant array of arrays. The middle of the array holds the address in the code where the program should return to after execution, and then the parameters are on one side whereas the local variables are on the other. The local variables have no clear sense of organization. Some compilers may detect that one value stops being used before another and just shares the memory location (you'd never notice unless you actually peeked in memory or scanned the stack).

As you can see, the two simply don't make sense. Calling free on a pointer indexing the stack means your trying to perform the list operation on the stack. One of two things will happen:

  1. Your implementation detects the memory is not even in the heap and blows up with an error message (illegal argument exception).

  2. The implementation is "dumb" and actually tries to perform the list operation. This means the value before the variable in memory will be altered and other values might be altered in an attempt to "merge" two free blocks into one larger block.

Simply put: don't do that. You might break something in your program. What if you messed up the return line? Next thing you know, you'd have an infinite loop of function calls yet... you wrote no loops. Very very bad.

And of course:

Your exact implementation of the heap will vary wildly, unlike the stack which doesn't tend to change much.

For instance, while I have never actually seen the code or a diagram of the raw memory of such a structure I have heard that there are models of the heap space built around there being two separate lists holding the freed blocks and the allocated blocks. This wouldn't affect the question though as there is still some form of internal bookkeeping that deals with the allocation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM