Deleting a heap and then dereferencing a pointer to that memory

This is the code from the exercise:

#include <iostream> using namespace std; int main() { int n = 13; int* ip = new int(n + 3); int* ip2 = ip; cout << *ip << endl; delete ip; cout << *ip2 << endl; cout << ip << tab << ip2 << endl; } 

When the space allocated for int on the heap is deleted, I thought that dereferencing the pointer would give some memory error. Instead, it returns 0.

Why is this?

+4
source share
4 answers

Calling an invalid pointer yields undefined results for each specification. This did not guarantee failure.

Usually (depending on the processor / OS / compiler / ...) the compiler does not care about this at all. It just gives what is currently at that memory address. For example, in the x86 architecture, you see an error only if the address is on a memory page that is not tied to your process (or your process does not have access to this access), so the exception will be thrown by the processor (protection error), which the OS will handle properly (and will likely cause your process to fail). Sometimes a trick is used so that access to address 0 always causes an access violation: the OS sets the read / write bits of the first page of the address space in the page table to 0, so that any access to this page will always throw an exception.

+14
source

This behavior is undefined, and therefore an implementation will occur and is system dependent.

+4
source

Highlighting the ip pointer will return what happens in that memory location at that time.

It returns 0 because it is that four bytes in ip occurs when encoding as an integer.

dereferencing a pointer after deleting it is unpredictable. It may be zero, it may be something else if this memory was redistributed elsewhere.

You just got lucky that it is 0 when you run your program.

+3
source

In response to Mehrdads answer: In gcc with glibc, data structures representing a bunch of memory are stored in the returned memory block to save memory (i.e. its obsessive list). Thus, when a block of memory is freed, it is added to the free list. My guess is that the 0, written after the free one, indicates that this is the last element of the list of free blocks (the first word with the freed pointer number contains the next pointer).

If you want to allocate and free more memory before playing this block again, the value will change when a new item is added to the end of the free list. This is one way to solve library decisions that affect what happens during undefined. In this case, the glibc developers took advantage of the fact that this behavior is undefined to make their memory allocator more economical.

If you run your program under valgrind, it will catch these errors for you. In any case, always stay away from undefined behavior, as it will probably differ on different platforms and even on different builds on the same platform (for example, debug vs release).

0
source

All Articles