According to theory of c programming variable a should be a dangling pointer and it should throw segmentation fault error.
There is no such theory or rule in C.
Memory allocation reserves memory for your use. Calling free
removes the reservation. The free
routine is not required to mark the memory as inaccessible.
The C standard defines an abstract model in which malloc
reserves space for an object, and free
ends the lifetime of that object. Within this model, two rules in the C standard apply in particular to your question. C 2018 6.2.4 2 says:
… If an object is referred to outside of its lifetime, the behavior is undefined…
As used in the C standard, “undefined” means the standard does not impose any requirements. That means the standard does not say you can access the memory, it does not say you cannot access the memory, it does not say your program will behave as if the object is still there, it does not say your program will behave as if they object is not there. It does not say whether your program will crash or not crash. The C standard simply says nothing about what will happen.
That paragraph also says:
… The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.
That means that, after free(a)
, the value of a
is indeterminate. It is no longer specified by the C standard. This rule in the C standard arose because some C implementations had to use various assistive means to refer to memory, such as a pointer containing data that referred to a table or structure with further information. Once the memory is freed, that table or structure may itself be altered or destroyed, and then attempting to use the pointer would fail in various ways. So, in the C model, the value of the pointer is indeterminate. This means your sentence “But here variable a is still pointing to same memory location” is not specified to be true by the C standard. And, while common modern C implementations do not have these pointers relying on additional data, the rule remains a rule, and compilers may take advantage of it in their optimization. So you cannot rely on the value of a pointer after it has been passed to free
.
To be clear: You not only cannot rely on the memory that was pointed to by the pointer, you cannot rely on the value of the pointer. Simply executing free(a); if (a == NULL) …
has undefined behavior.