Does freeing structures in C also delete its members? [duplicate] - c

This question already has answers here:
Will freeing a structure pointer also free the memory allocated inside of the structure in C?
(2 answers)
Closed 3 years ago.
I'm pretty much new to C and i have a question about allocating memory. So I tried this code below that should free the structure elem1.
struct elem{
char *data1;
char *data2;
};
int main()
{
struct elem *elem1 = malloc(sizeof(struct elem));
elem1->data1 = "abc";
elem1->data2 = "def";
char *a = elem1->data1;
char *b = elem1->data2;
free(elem1);
printf("%s\n%s\n",a,b);
return 0;
}
The code compiles just fine and it gives back,
abc
def
I expected it to fail since free should also free the memory of its members. But why does it work? And what should I do if I want to access the members of the structure after I free the structure?

The members are part of the structure. Freeing the structure deallocates all of its members.
However, in your example, the members are just pointers. You're copying a pointer into the structure (node->data1 = ...), then out of the structure (... = node->data1), then freeing the structure. None of this affects the memory that the pointer is pointing to.
In your example the actual strings are stored in static memory (they're string literals). That means they're never destroyed; they live as long as the program is running. That's why it's perfectly safe to print them. Your code is fine.
Finally, accessing freed memory has undefined behavior (meaning anything can happen, including a program crash or appearing to work correctly). If you want to access members of a structure that has been freed, just do that:
struct elem *p = malloc(sizeof *p);
free(p);
p->data1 = "boom!"; // Undefined behavior!
However, that would be a bug, so ... don't, please.

Every malloc has to be balanced with a corresponding free.
Your assignment node->data1 = "abc"; assigns a pointer to the read-only literal "abc", so there is no dynamic memory here, and therefore you must not use a free.
In your particular case, you are able to retain that pointer a having called free on the struct since you did not have to free that memory and it didn't ever belong to the struct. But that does not work in general: if you had used malloc to set node->data1 then (1) you would have to call free on that pointer before you attempt to call free on the struct, and (2) the behaviour of a subsequent deference of node->data1 would be undefined.

Related

malloc'd pointer inside struct that is passed by value

I am putting together a project in C where I must pass around a variable length byte sequence, but I'm trying to limit malloc calls due to potentially limited heap.
Say I have a struct, my_struct, that contains the variable length byte sequence, ptr, and a function, my_func, that creates an instance of my_struct. In my_func, my_struct.ptr is malloc'd and my_struct is returned by value. my_struct will then be used by other functions being passed by value: another_func. Code below.
Is this "safe" to do against memory leaks provided somewhere on the original or any copy of my_struct when passed by value, I call my_struct_destroy or free the malloc'd pointer? Specifically, is there any way that when another_func returns, that inst.ptr is open to being rewritten or dangling?
Since stackoverflow doesn't like opinion-based questions, are there any good references that discuss this behavior? I'm not sure what to search for.
typedef struct {
char * ptr;
} my_struct;
// allocates n bytes to pointer in structure and initializes.
my_struct my_func(size_t n) {
my_struct out = {(char *) malloc(n)};
/* initialization of out.ptr */
return out;
}
void another_func(my_struct inst) {
/*
do something using the passed-by-value inst
are there problems with inst.ptr here or after this function returns?
*/
}
void my_struct_destroy(my_struct * ms_ptr) {
free(ms_ptr->ptr);
ms_ptr->ptr = NULL;
}
int main() {
my_struct inst = my_func(20);
another_func(inst);
my_struct_destroy(&inst);
}
I's safe to pass and return a struct containing a pointer by value as you did it. It contains a copy of ptr. Nothing is changed in the calling function. There would, of course, be a big problem if another_func frees ptr and then the caller tries to use it or free it again.
Locality of alloc+free is a best practice. Wherever possible, make the function that allocates an object also responsible for freeing it. Where that's not feasible, malloc and free of the same object should be in the same source file. Where that's not possible (think complex graph data structure with deletes), the collection of files that manage objects of a given type should be clearly identified and conventions documented. There's a common technique useful for programs (like compilers) that work in stages where much of the memory allocated in one stage should be freed before the next starts. Here, memory is only malloced in big blocks by a manager. From these, the manager allocs objects of any size. But it knows only one way to free: all at once, presumably at the end of a stage. This is a gcc idea: obstacks. When allocation is more complex, bigger systems implement some kind of garbage collector. Beyond these ideas, there are as many ways to manage C storage as there are colors. Sorry I don't have any pointers to references (pun intended :)
If you only have one variable-length field and its size doesn't need to be dynamically updated, consider making the last field in the struct an array to hold it. This is okay with the C standard:
typedef struct {
... other fields
char a[1]; // variable length
} my_struct;
my_struct my_func(size_t n) {
my_struct *p = malloc(sizeof *p + (n - 1) * sizeof p->a[0]);
... initialize fields of p
return p;
}
This avoids the need to separately free the variable length field. Unfortunately it only works for one.
If you're okay with gcc extensions, you can allocate the array with size zero. In C 99, you can get the same effect with a[]. This avoids the - 1 in the size calculation.

Difference in creating a struct using malloc and without malloc

Could someone please explain to me the difference between creating a structure with and without malloc. When should malloc be used and when should the regular initialization be used?
For example:
struct person {
char* name;
};
struct person p = {.name="apple"};
struct person* p_tr = malloc(sizeof(struct person));
p_tr->name = "apple";
What is really the difference between the two? When would one approach be used over others?
Having a data structure like;
struct myStruct {
int a;
char *b;
};
struct myStruct p; // alternative 1
struct myStruct *q = malloc(sizeof(struct myStruct)); // alternative 2
Alternative 1: Allocates a myStruct width of memory space on stack and hands back to you the memory address of the struct (i.e., &p gives you the first byte address of the struct). If it is declared in a function, its life ends when the function exits (i.e. if function gets out of the scope, you can't reach it).
Alternative 2: Allocates a myStruct width of memory space on heap and a pointer width of memory space of type (struct myStruct*) on stack. The pointer value on the stack gets assigned the value of the memory address of the struct (which is on the heap) and this pointer address (not the actual structs address) is handed back to you. It's life time never ends until you use free(q).
In the latter case, say, myStruct sits on memory address 0xabcd0000 and q sits on memory address 0xdddd0000; then, the pointer value on memory address 0xdddd0000 is assigned as 0xabcd0000 and this is returned back to you.
printf("%p\n", &p); // will print "0xabcd0000" (the address of struct)
printf("%p\n", q); // will print "0xabcd0000" (the address of struct)
printf("%p\n", &q); // will print "0xdddd0000" (the address of pointer)
Addressing the second part of your; when to use which:
If this struct is in a function and you need to use it after the function exits, you need to malloc it. You can use the value of the struct by returning the pointer, like: return q;.
If this struct is temporary and you do not need its value after, you do not need to malloc memory.
Usage with an example:
struct myStruct {
int a;
char *b;
};
struct myStruct *foo() {
struct myStruct p;
p.a = 5;
return &p; // after this point, it's out of scope; possible warning
}
struct myStruct *bar() {
struct myStruct *q = malloc(sizeof(struct myStruct));
q->a = 5;
return q;
}
int main() {
struct myStruct *pMain = foo();
// memory is allocated in foo. p.a was assigned as '5'.
// a memory address is returned.
// but be careful!!!
// memory is susceptible to be overwritten.
// it is out of your control.
struct myStruct *qMain = bar();
// memory is allocated in bar. q->a was assigned as '5'.
// a memory address is returned.
// memory is *not* susceptible to be overwritten
// until you use 'free(qMain);'
}
If we assume both examples occur inside a function, then in:
struct person p = {.name="apple"};
the C implementation automatically allocates memory for p and releases it when execution of the function ends (or, if the statement is inside a block nested in the function, when execution of that block ends). This is useful when:
You are working with objects of modest size. (For big objects, using many kibibytes of memory, malloc may be better. The thresholds vary depending on circumstances.)
You are working with a small number of objects at one time.
In:
struct person* p_tr = malloc(sizeof(struct person));
p_tr->name = "apple";
the program explicitly requests memory for an object, and the program generally should release that memory with free when it is done with the object. This is useful when:
The object must be returned to the caller of the function. An automatic object, as used above, will cease to exist (in the C model of computation; the actual memory in your computer does not stop existing—rather it is merely no longer reserved for use for the object) when execution of the function ends, but this allocated object will continue to exist until the program frees it (or ends execution).
The object is very large. (Generally, C implementations provide more memory for allocation by malloc than they do for automatic objects.)
The program will create a variable number of such objects, depending on circumstances, such as creating linked lists, trees, or other structures from input whose size is not known before it is read.
Note that struct person p = {.name="apple"}; initializes the name member with "apple" and initializes all other members to zero. However, the code that uses malloc and assigns to p_tr->name does not initialize the other members.
If struct person p = {.name="apple"}; appears outside of a function, then it creates an object with static storage duration. It will exist for the duration of program execution.
Instead of struct person* p_tr = malloc(sizeof(struct person));, it is preferable to use struct person *p_tr = malloc(sizeof *p_tr);. With the former, a change to the p_tr requires edits in two places, which allows a human opportunity to make mistakes. With the latter, changing the type of p_tr in just one place will still result in the correct size being requested.
struct person p = {.name="apple"};
^This is Automatic allocation for a variable/instance of type person.
struct person* p_tr = malloc(sizeof(person));
^This is dynamic allocation for a variable/instance of type person.
Static memory allocation occurs at Compile Time.
Dynamic memory allocation means it allocates memory at runtime when the program executes that line of instruction
Judging by your comments, you are interested in when to use one or the other. Note that all types of allocation reserve a computer memory sufficient to fit the value of the variable in it. The size depends on the type of the variable. Statically allocated variables are pined to a place in the memory by the compiler. Automatically allocated variables are pinned to a place in stack by the same compiler. Dynamically allocated variables do not exist before the program starts and do not have any place in memory till they are allocated by 'malloc' or other functions.
All named variables are allocated statically or automatically. Dynamic variables are allocated by the program, but in order to be able to access them, one still needs a named variable, which is a pointer. A pointer is a variable which is big enough to keep an address of another variable. The latter could be allocated dynamically or statically or automatically.
The question is, what to do if your program does not know the number of objects it needs to use during the execution time. For example, what if you read some data from a file and create a dynamic struct, like a list or a tree in your program. You do not know exactly how many members of such a struct you would have. This is the main use for the dynamically allocated variables. You can create as many of them as needed and put all on the list. In the simplest case you only need one named variable which points to the beginning of the list to know about all of the objects on the list.
Another interesting use is when you return a complex struct from a function. If allocated automatically on the stack, it will cease to exist after returning from the function. Dynamically allocated data will be persistent till it is explicitly freed. So, using the dynamic allocation would help here.
There are other uses as well.
In your simple example there is no much difference between both cases. The second requires additional computer operations, call to the 'malloc' function to allocate the memory for your struct. Whether in the first case the memory for the struct is allocated in a static program region defined at the program start up time. Note that the pointer in the second case also allocated statically. It just keeps the address of the memory region for the struct.
Also, as a general rule, the dynamically allocated data should be eventually freed by the 'free' function. You cannot free the static data.

free(struct variable) doesn't clear previous stored values associated with that variable when I malloc again?

I created a struct like the following:
typedef struct header{
int hc;
char src[18];
char dst=[18];
char reason[15];
char d[3];
char m[3];
char y[4];
struct measurements{
char h_ip[17];
int h_ttl;
int h_id;
float h_rtt;
}HOPS[100];
}HEADER;
INSIDE MAIN:
HEADER *head;
for(...){
head=(HEADER*) malloc(sizeof(HEADER));
.....
free(head);
}
Will the above malloc automatically allocate memory for the inner struct as well? Also, I'm facing a weird problem here. After I free the header, I'm still able to print the values of head->HOPS[i].h_ip. Should I explicitly free the inner struct as well so that even the values get cleared?
Yes, it allocates memory for the inner structure. And you need not free the inner structure separately.
If you have a pointer defined inside your structure, in that case you have to allocate separately for that pointer member of the structure and free that separately.
Consider freeing memory as a black box. All what you know is that after freeing you shouldn't refer to freed memory.
You may find that that memory block still exists and still contains some old values. That's ok: it just was marked as freed and probably it will be used again soon by allocator.
For example when you call malloc again and realized that just allocated block contains values from the old structure. It happens and that's alright. Just use this block as usually.
So, after the problem with the wrong declaration of head was resolved:
free returns a previously allocated memory block to the heap. It does not clear anything (for performance reasons). However, you are not supposed to access that block anymore afterwards. Doing so results in undefined behaviour and might let your computer fly out of the window.
Worst that can happen is ... nothing ... Yes, you might even not notice anything strang happens. However, that does not mean your program run correctly, it just does not show any symptoms.
To catch illegal accesses, you might set the pointer to NULL once you freed the object it points to. Some operating systems catch accesses to addresses near the null pointer address, but there is no guarantee. It is a good practice anyway and does no harm.
For your other question: malloc allocates a block of memory large enough to store that many bytes you passed as argument. If it cannot, it will return a null pointer. You should always check if malloc & friends returned a valid pointer (i.e. not a null pointer).
int *p = malloc(sizeof(int));
if ( p == NULL ) {
error: out of memory
}
...
Notice the omission of the cast of the result of malloc. In C you should not cast void * as returned by malloc & friends (but also elsewhere). As much as you did not for free(head). Both take the same type: void *, btw. (so why cast one and not the other?). Note that in C any object pointer can freely be assigned to/from void * without cast. Warning functions are no objects in the C standard!
Finally: sizeof(HEADER) returns the size of the struct. Of course that include all fields. A nested struct is a field. A pointer to another struct is a field. For the latter, however note: the pointer itself is a field, but not what it points to! If that was another struct, you have to malloc that seperately **and also free seperately (remember what I wrote above).
But as you do not have pointer inside your struct, that is not your problem here. (keep it in mind, if you continue programming, you will eventually need that!)

Can I check if a pointer was allocated by malloc/calloc/realloc? [duplicate]

This question already has answers here:
Check if a pointer points to allocated memory on the heap
(10 answers)
Can you determine if a string if freeable in C? [duplicate]
(5 answers)
Closed 9 years ago.
I was wondering is it possible to check if a pointer passed into a function was allocated by malloc/calloc/realloc?
int main(){
struct something o;
struct something *a;
a = malloc(sizeof(struct something));
freeSome(&o);/*This would normally throw an (corruption?) error*/
freeSome(a);/*This is fine*/
}
void freeSome(struct something * t){
if (/*expression here*/){
free(t);
}
}
I understand that usually you check to see if t == NULL, but I was just wondering if it was possible to see if memory has been allocated for the given pointer.
No, you can't.
Basically, you should not need to do this. If you are wanting to write a helper function to free some memory given a pointer, than you should awarely and explicitely pass a dynamically allocated pointer to a certain area of memory to do so.
Raw pointers in C cannot transport extra informations about the memory they are pointing to. If you want to have such informations, you will have to pass an additional wrapper that holds the pointer you are interested in, such as :
typedef struct my_pointer
{
void *ptr;
int is_dynamically_allocated;
} ptr;
But this would be a huge loss of memory/time.
No way to check, you ought to NULL initialize and then test whether NULL indeed
From section 7.20.3.2 The free function of C99 standard:
The free function causes the space pointed to by ptr to be deallocated, that is,
made available for further allocation. If ptr is
a null pointer, no action occurs. Otherwise, if the argument does not
match a pointer earlier returned by the calloc, malloc, or realloc
function, or if the space has been deallocated by a call to free or
realloc, the behavior is undefined.

C struct memory management

Another C question:
let's say I have a struct that has a pointer member of char* type.
When I want to initialize an instance of the struct I call malloc:
MyStruct* ptr = (MyStruct*)malloc(sizeof(MyStruct)
And then allocate 256 bytes of memory for the char* member:
ptr->mem = (char*)malloc(sizeof(char)*256);
what happens to the pointer member and the memory it points to when I call
free(ptr);?
when I check the program with valgrind I see that I have a memory leak, but when I explicitly call free(ptr->member); I still have a memory leak and valgrind shows an "Invalid free" error
What's the proper way the manage the memory pointed by the member?
You have to free ptr->member first, then the struct
free(ptr->member);
free(ptr);
As soon as you call free(ptr), none of the members in ptr are valid any more. You can't do anything with them. But the memory that was pointed to be ptr->mem still needs to be freed. So you must either free(ptr->mem) first, or have otherwise copied that pointer somewhere so have a valid pointer to free.
The general pattern of allocating and freeing compound structures is something like (and it is helpful to wrap them up in nice clean functions that do this):
MyStruct* MakeMyStruct() {
MyStruct* ptr = malloc(sizeof(MyStruct)); //N.B. don't need cast if it's C
ptr->mem = malloc(sizeof(char)*256);
//initialise other members
return ptr;
}
void DestroyMyStruct(MyStruct *ptr) {
//Free members first, then the struct
free(ptr->mem);
free(ptr);
}
If some of the members are complicated structs themselves, they would in turn be allocated/freed with MakeWhatever and DestroyWhatever instead of malloc and free in the above two functions.
The rule of thumb is that you need one free for every (successful) call to malloc (and generally, these occur in the reverse order).
If you only free(ptr), then you have a memory leak (because there's no way to access the memory allocated for ptr->mem). If you only free(ptr->mem), then you haven't cleared up completely (not quite as bad as a memory leak).

Resources