Using a pointer after free ()

During my tests, I found that you can use a pointer after free (). I have the following code:

typedef struct{ int module_id; int adc_id; struct config_line * pnext; } config_line; config_line * create_list() { config_line * phead = (config_line *) malloc(sizeof(config_line)); phead->pnext=NULL; phead->module_id = 1; phead->adc_id = 2; printf("module_id=%d adc_id=%d\n",phead->module_id, phead->adc_id); free(phead); printf("module_id=%d adc_id=%d\n",phead->module_id, phead->adc_id); phead->module_id = 2; phead->adc_id = 5; printf("module_id=%d adc_id=%d\n",phead->module_id, phead->adc_id); } 

The output of this code is:

 module_id=1 adc_id=2 module_id=0 adc_id=2 module_id=2 adc_id=5 

Why after free (phead) can I access (read and write) to the pointer? Why does not a segmentation error occur?

+4
source share
5 answers

Since using an invalid pointer causes undefined behavior. And that means the behavior ... well ... undefined. This is not required to fail.

+18
source

When you call free(phead) , the phead memory phead indicates freeing, but the phead value remains untouched, making phead dangling pointer. Accessing freed memory creates undefined behavior.

It is good practice to assign a NULL pointer to a pointer when you free the memory it points to:

 free(phead); phead = NULL; 
+9
source

Since memory is still mapped in your process but not allocated. C program has two levels of memory management: firstly, the kernel gives you pages that you can write to. If a process requires more memory that it has mapped, it must request more from the kernel (sbrk). This happens in large chunks, so malloc cuts it into chunks for you, requesting more pages as needed, but using, where possible, the memory already allocated for the program. free cannot return the page until all the resources allocated by it are freed.

Thus, the memory access violations that the kernel (SIGSEGV) gives are rather gross and cannot display most memory errors, but only things that are fatal in terms of the kernel. You can delete malloc tracking data, read it to the end of most distributions, and after many free ones, etc.

However, never make memory errors. Launch the application with valgrind, which uses a very strict virtual machine to check all errors and crush them immediately.

+4
source

Since freeing memory (pointer) just returns that memory to the free memory pool. The memory does not just disappear, and its contents are not cleared until this memory is allocated again and written.

Thus, it is very easy to access memory after it is freed. Itโ€™s just not a good idea, as you can imagine, because it can be assigned at any time and changed.

+4
source

Why can a chick continue to run and jump despite being chopped off? Note that this does not always happen; some chickens may stop moving immediately, while others may continue to work for several months . When this happens, it happens because it happens. Does this mean that we should turn off our pets?

Like cutting our pets headlong, using freed memory is a bad idea. This does not mean that it will lead to negative results; your program may continue to run as expected on your computer, and if (fubar) (where fubar is your invalid pointer) may be enough to cause your program to crash in other implementations.

This idea of โ€‹โ€‹freedom of implementation to define (or not) behavior is formally known as undefined behavior; the behavior is undefined because the C standard, a set of documents defining the behavior of a C implementation, does not define behavior. Therefore, like cutting our pets, we must avoid undefined behavior.

+2
source

Source: https://habr.com/ru/post/1469497/


All Articles