Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I still access a member of a struct after the pointer to it is freed?

If I define a structure...

struct LinkNode
{
  int node_val;
  struct LinkNode *next_node;
};

and then create a pointer to it...

struct LinkNode *mynode = malloc(sizeof(struct LinkNode));

...and then finally free() it...

free(mynode);

...I can still access the 'next_node' member of the structure.

mynode->next_node

My question is this: which piece of the underlying mechanics keeps track of the fact that this block of memory is supposed to represent a struct LinkNode? I'm a newbie to C, and I expected that after I used free() on the pointer to my LinkNode, that I would no longer be able to access the members of that struct. I expected some sort of 'no longer available' warning.

I would love to know more about how the underlying process works.

like image 659
Ducain Avatar asked May 09 '13 17:05

Ducain


1 Answers

The compiled program no longer has any knowledge about struct LinkedNode or field named next_node, or anything like that. Any names are completely gone from the compiled program. The compiled program operates in terms of numerical values, which can play roles of memory addresses, offsets, indices and so on.

In your example, when you read mynode->next_node in the source code of your program, it is compiled into machine code that simply reads the 4-byte numerical value from some reserved memory location (known as variable mynode in your source code), adds 4 to it (which is offset of the next_node field) and reads the 4-byte value at the resultant address (which is mynode->next_node). This code, as you can see, operates in terms of integer values - addresses, sizes and offsets. It does not care about any names, like LinkedNode or next_node. It does not care whether the memory is allocated and/or freed. It does not care whether any of these accesses are legal or not.

(The constant 4 I repeatedly use in the above example is specific for 32-bit platforms. On 64-bit platforms it would be replaced by 8 in most (or all) instances.)

If an attempt is made to read memory that has been freed, these accesses might crash your program. Or they might not. It is a matter of pure luck. As far as the language is concerned, the behavior is undefined.

like image 145
AnT Avatar answered Nov 01 '22 17:11

AnT