Is it okay to call free on a pointer which is pointing at the first member of a struct (and the struct is the one involved with malloc)? I know in principle the pointer is pointing at the right thing anyway...
struct s {int x;};
//in main
struct s* test;
test = (struct s*) malloc(sizeof(*test));
int* test2;
test2 = &(test->x);
free(test2); //is this okay??
Also, will the answer change if int x
is replaced with a struct?
Update: Why would I want to write code like this?
struct s {int x;};
struct sx1 {struct s test; int y;}; //extending struct s
struct sx2 {struct s test; int z;}; //another
// ** some functions to keep track of the number of references to each variable of type struct s
int release(struct s* ptr){
//if the number of references to *ptr is 0 call free on ptr
}
int main(){
struct sx1* test1;
struct sx2* test2;
test1 = (sx1*) malloc(sizeof(*sx1));
test2 = (sx2*) malloc(sizeof(*sx2));
//code that changes the number of references to test1 and test2, calling functions defined in **
release(test1);
release(test2);
}
Dereferencing a free'd pointer is undefined behavior. It will most likely not crash since it's still pointing to some real memory, but the contents may not be what you expect it to be. In short, don't do it!
The function free takes a pointer as parameter and deallocates the memory region pointed to by that pointer. The memory region passed to free must be previously allocated with calloc , malloc or realloc . If the pointer is NULL , no action is taken.
Calling free() twice on the same value can lead to memory leak. When a program calls free() twice with the same argument, the program's memory management data structures become corrupted and could allow a malicious user to write values in arbitrary memory spaces.
C standard only says that calling free twice on a pointer returned by malloc and its family function invoke undefined behavior. There is no further explanation why it is so.
Yes this is ok.
6.7.2.1
- Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.
Which means that this is defined:
struct s {int x;};
struct s* test;
test = (struct s*) malloc(sizeof(*test));
int* p = &(test->x);
free(p);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With