Let’s look at the code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *ponteiro1 = malloc(sizeof(int));
*ponteiro1 = 5;
int *ponteiro2 = ponteiro1;
printf("%p == %p, %d == %d\n", (void *)ponteiro1, (void *)ponteiro2, *ponteiro1, *ponteiro2);
free(ponteiro2);
printf("%p == %p, %d == %d", (void *)ponteiro1, (void *)ponteiro2, *ponteiro1, *ponteiro2);
}
Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.
It shows that the two variables have the same value, and that value is the pointer. We also see, obviously, that the value contained in the allocated memory is the same when we slip the pointer and access the pointed object, after all if it is the same address in the variables then we point certainly to the same object. Nor could it be different, nowhere did the code create 2 objects.
If you consider that free()
releases a memory address when it is released nothing else at that point should be used. In the same way that you allocated only once you should release only once. There are no two allocations. Assigning one variable to another is not creating a new allocation. In C you have to be explicit in everything.
Even if you try to release again you will have one undefined behavior.
It is important to note that the value of the variable is not reset, you should not try to access this address after a free()
.
Some people like to reset the value of the variable to avoid an undetected access. If you reset and try to access later it will probably break the application which is better than working by coincidence and at another time give wrong result without warning.
If it is not clear, the value of the variable that is of the pointer type is never the value of the object, there are two completely different values in memory, this type always causes a indirect to access the real object.
Zeroing value of object
What I found curious is that after the free()
the value of the object allocated to that address was considered 0. It gives the impression that the function free()
It was worth it, but it’s not meant to be. Of course the compiler is free to do whatever he wants, but it would cost and C encourages not to put hidden costs that may not be necessary. In general the simple release will still allow access to the value of the object if nothing overwrites it.
Searching a little it seems that there is case that the release of application memory can free the memory to the operating system. This occurring the address is not released to access by the application. Interestingly does not give error and only accesses a neutral value. I stood on my head because it probably costs something. Doesn’t mean it’s that, there may be a change in the same value, you’d have to search his compiler or library to identify what he does.
It may happen only in mode debug, what I do not like the idea because it changes the semantics of the code, it can even hide a bug. It would make more sense because in this mode the performance is not problem, but it seems a bad solution.
Gazing the source allocation may have occurred a half-term:
struct malloc_chunk {
INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
struct malloc_chunk* bk_nextsize;
};
An allocation block may have overwritten in this situation the value of the object. This does not mean that it will always occur, but happened a case that did not release to the operating system, but had an internal memory management processing that used the memory within the free()
.
Then I keep thinking that even the printf()
could, in theory, have done something that overwritten the value while he was processing the print. I don’t think it’s good and I think it’s less likely. I don’t remember this function making an allocation on heap.
More about
segmentation fault
: https://pt.wikipedia.org/wiki/Falha_de_segmenta%C3%A7%C3%A3o– Maf