C freeing struct pointer members - c

I have the following structure that I've declared:
typedef struct binTreeNode
{
void *data;
struct binTreeNode *left;
struct binTreeNode *right;
} myBinaryTreeNode;
In my main function, I'm trying to use a pointer to an instance of that structure called root.
myBinaryTreeNode *root = malloc(sizeof(myBinaryTreeNode));
printf("\nPlease insert root data: ");
int input;
scanf("%d", &input);
root->data = (void*)&input;
printInt(root->data);
free(root);
this code runs perfectly well. But, I thought that when you have a struct with members that are pointers, you should free() each one of them (additionally to the pointer to the struct).
So here, I didn't malloc for root->data (because I think that mallocing the struct does that), but it is initialized to the input value and it's value gets printed successfully. When I try to free(root->data) my program crashes.
So root->data is not malloced when I malloc root? If not, how can I still use it?
Why does this happen? What am I missing here?

First, get the concept of where and how you need to (or need not) call free().
You don't need to malloc() "for" root->data, that variable is already allocated while you allocated memory equal to the size of the structure. Now, next, you certainly need root->data to point to some valid memory, so that you can dereference the pointer to read from to write into it. You can do that by either of two ways
store an address which is valid (like in your case, supply the address of an already existing variable)
assign a pointer returned by another malloc() (success).
In case, you're storing the pointer returned by malloc(), yes you must free() the memory but in your case, root->data holds a pointer not returned by malloc(), so it does not need free()-in either.
Just to add and emphasis on the part related to free()-ing, you must not attempt to free() the memory which has not been previously allocated by a call to malloc() and family otherwise, it invokes undefined behavior. To quote, standard C11, chapter §7.22.3.3, (emphasis mine)
void free(void *ptr);
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 a memory management
function, or if the space has been deallocated by a call to free or realloc, the
behavior is undefined.

data member points to input local variable, so you cannot free it.
You must free members if you dynamically allocate them, like
typedef struct binTreeNode
{
int *data;
struct binTreeNode *left;
struct binTreeNode *right;
} myBinaryTreeNode;
root->data = malloc(sizeof(int));
scanf("%d", root->data);
free(root->data);

When I try to free(root->data) my program crashes.
You cannot free memory that you have not dynamically allocated. If you want to free the elements, you should first allocate them this way :
typedef struct binTreeNode
{
int *data;
struct binTreeNode *left;
struct binTreeNode *right;
} myBinaryTreeNode;
root->data = malloc(sizeof(int));
if (root->data == NULL)
{
printf("Error allocating memory\n");
return;
}
scanf("%d", root->data);
free(root->data);
Note that you should check the result of malloc before continuing.
So root->data is not malloced when I malloc root? If not, how can I still use it?
Note also that space for root->data is allocated when you allocate memory for the struct, but it is not malloced. You need an extra malloc especially for root->data, as shown in the example above. The reason why you need malloc for root->data is to be able to dereference the pointer.

I have added some annotations to your code.
I hope this clears things up.
// I have added an enclosing block for the purpose of demonstration:
{
// Here you allocate memory for a tree node object with dynamic/allocated
// storage duration.
// That is: three pointers, that point to nowhere are created and will
// exist until the memory holding them is free'd.
myBinaryTreeNode *root = malloc(sizeof(myBinaryTreeNode));
printf("\nPlease insert root data: ");
// Here you create an object with automatic storage duration.
// That is, the object is automatically destroyed when the function
// returns or the block is closed: { ... }
int input;
// here you attempt to assign a value to the variable
// (you should check the return value: the input may fail)
scanf("%d", &input);
// Here you assign the address of an object to a pointer.
// Note that you are only allowed to use the pointer as long as the
// object it points to "lives".
root->data = (void*)&input;
// Here you probably print the value, or the pointer address, or something else
printInt(root->data);
free(n); // <-- Where and how did you allocate this?
// Here you free the memory holding the tree node
free(root);
} // <-- At this point the "input" variable is automatically destroyed.
You should really read up on the different storage durations (automatic and dynamic/allocated) and the purpose of dynamic memory allocation:
http://en.cppreference.com/w/c/language/storage_duration
http://en.cppreference.com/w/c/language/lifetime
C Memory Management
To address the questions in detail:
When I try to free(root->data) my program crashes.
That is because you can only free() what you have malloc(). Memory management is different for the different types of storage duration.
So root->data is not malloced when I malloc root?
Memory for the pointer is allocated, but it doesn't "own" or "point to" any object by default.
If not, how can I still use it?
Just as you did. You assign a memory address of an object to it, that lives long enough for you to use it. You can produce such object using dynamic memory management (then take care that you destroy it manually once you're done: don't leak memory) or using "automatic memory management" as you have done (then take care that it isn't destroyed too early: don't access invalid memory). (To name just two of the possible ways to create an object...)

Related

How to release a struct that wasn't called with malloc?

Assume I have a struct node like such:
struct node {
struct other_struct value;
int some_num;
}
I have seen snippets of code where the struct can be initialized without calling malloc, like this:
struct node my_node;
my_node.value = NULL;
my_node.some_num = 2;
And then value can later be malloced. However, how would I free my_node?
my_node is allocated on the stack, and once it goes out of scope, its memory is automatically deallocated.
Use malloc if you want to allocate something on the heap, and it will persist until you free it. For your example, you would do:
struct node *my_node = malloc(sizeof(struct node));
my_node->some_num = 2;
// Sometime later
free(my_node);
Space will also be allocated for the value field if you malloc (as long as you pass the right size) or if you declare on the stack. sizeof(struct node) includes the size of other_struct.
Currently with those code snippets you can't really free value or my_node, as they're both just static variables, if in your node structure, the other_struct field was a pointer, then you could dynamically allocate some memory, and save the address in that pointer.
Then when done, free the pointer value.
If then, my_node was also a pointer (which I think is what you want), you would need to allocate memory for the node struct, and save the address to the pointer my_node. THEN, allocate some memory for the other_struct struct and save it to the pointer value. And after you're done, you would free value FIRST, then free my_node.
When doing things like this, I generally create a little constructor/destructor function, which will do it all for me. It can be too easy to forget to free the inner pointer (value) and just free the outer pointer (mynode). Then that would cause a memory-leak, as value would still be allocated and taking up room in memory.
The code:
struct node {
struct other_struct value;
int some_num;
};
defines value to be a member of struct node. It is a part of struct node. Whenever a struct node is created, it will contain the member named value, and no other memory needs to be allocated for value. Whether a struct node is created automatically or by malloc or other means, its memory will always include memory for value.
If you changed it to:
struct node {
struct other_struct *value;
int some_num;
}
then value would be a pointer to a struct other_struct, and you would need to provide memory for it to point to.
In this code:
struct node my_node;
my_node.value = NULL;
my_node.some_num = 2;
the object my_node is created automatically, and you do not have to do anything to release it or its members; that will happen automatically. You cannot use my_node.value = NULL because value is a structure, not a pointer.
If the structure definition is changed so that value is a pointer, then you can set to NULL, or you can set it to point at an existing object, or you can allocate memory for it and set it to point to the allocated memory. If you allocate memory for it, then you should ensure that memory is later freed (except it is okay not to free it if you are intentionally keeping it to the end of program execution anyway, and you are executing in user mode on a general-purpose operating system).
You don't free it... it is destroyed, when the block it has been declared in is abandoned by the program.
Let's say that this variable is defined at the beginning of a function's body block. When the function is being called, the function creates this variable as it's a local. When the function terminates, all local variables are destroyed, so it is your local structure.
If you declare such a variable out of any function, then your variable has global duration, and it is created at program initialization, and lives as much as the program itself.

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.

How to initialize a struct using pointer?

I am new to C, and I am facing this problem when practicing.
The struct:
typedef struct {
char name[20];
int score[3];
int no;
} Student;
The initialize:
Student *pStudent;
strcpy(pStudent->name,"Kven");
pStudent->score[0]=1;
pStudent->score[1]=2;
pStudent->score[2]=3;
pStudent->no=1;
If the "pStudent" is not a pointer I can get it right. But if it is a pointer, I will always get a "bad access" error. How to solve it if I must use a pointer? Thank you.
A variable of type pointer stores the address in memory of another variable (it points to another variable).
Your variable pStudent is not initialized. It doesn't point to anything. In fact, it contains some garbage value that, most of the times, is the address of a memory area where the program is not allowed to write. This is why when you attempt to write there (the call to strcpy()) the operating system slaps your program over its "hand" and terminates it with the error message you mentioned.
How to correctly use pointers
One usage of pointers is to point to a certain variable that is statically allocated (defined in the program):
Student s, *pStudent = &s;
This example declares the variable s of type Student and the variable pStudent that points to it. Notice it is initialized with &s which is the address of s. Now, your code uses pStudent to initialize the fields of s.
Another usage of pointers is to dynamically allocate memory during runtime:
Student *pStudent;
pStudent = malloc(sizeof(Student));
In this situation, pStudent is initialized with the address of a new variable of type Student that is created during runtime (it doesn't have a name) by calling malloc(). malloc() allocates a block of memory (of the specified size) and return its address.
When you don't need it, you have to free the memory allocated by malloc() (using free()) for reuse:
free(pStudent);
After this call, the value of the variable pStudent doesn't change, it still points to the same address but it is invalid and using it produces undefined behaviour. You have to put the address of another Student structure in pStudent (using one of the two ways presented here) before using it again.
Student *pStudent;
should be
Student *pStudent = malloc(sizeof(Student));
Allocate memory for the pointer before writing data once done using it
free(pStudent);
Student *pStudent;
creates a pointer of type Student*. This pointer is not initialized and points to some "random" location. Allocate memory for it using malloc(or calloc) from stdlib.h:
pStudent = malloc(sizeof(Student));
and then free it after its use using:
free(pStudent);
You don't allocate any memory, you just allocate a pointer. You'll need to study pointers and how they work.
Fix the code like this:
Student student;
strcpy(student.name,"Kven");
student.score[0]=1;
student.score[1]=2;
student.score[2]=3;
student.no=1;
Alternatively you could allocate memory dynamically. But it doesn't make any sense in this case (and yet I bet at least 3 people will post answers telling you to do that...). Plus you really need to study pointers before doing dynamic allocation.
Student *pStudent = calloc(1, sizeof(Student);
if(pStudent == NULL)
{
// error handling
}
strcpy(pStudent->name,"Kven");
pStudent->score[0]=1;
pStudent->score[1]=2;
pStudent->score[2]=3;
pStudent->no=1;
...
free(pStudent);
You need to allocate memory for your structure first.
You can allocate memory with:
Student *pStudent = malloc(sizeof(Student));
And then you must release it at the end with
free(pStudent);

Malloc for character array and Structures

In this question the usage of malloc for character arrays is explained in a detailed way.
When should I use malloc in C and when don't I?
Is this same for structures in C?
For example consider the following definition:
struct node
{
int x;
struct node * link;
}
typedef struct node * NODE;
Consider the following two usage of the above structure:
1)
NODE temp = (NODE) malloc(sizeof(struct node));
temp->x =5;
temp->link = NULL;
2)
struct node node1, *temp;
node1.x = 5;
node1.link = NULL;
temp = &node1;
Can I use the declaration of temp from the second example and modify the node1.link point to another structure struct node node2 by using temp->link = &node2 (pointer to node2 structure)?
Here, this implementation is used for creating a tree data structure.
Will the structures also follow the same rules as like arrays as stated in the above link?
Because many implementations I have seen followed the first usage. Is there any specific reason for using malloc ?
You can do what you describe in #2, but remember that it will only work as long as node1 is in scope. If node1 is a local variable in a function, then when the function returns, the memory location it refers to will be reclaimed and used for something else. Any other pointers in your program which still point to &node1 will no longer be valid. One of the advantages of using malloc to allocate memory dynamically is that it remains valid until you call free to dispose of it explicitly.
the first usage use the heap memory which is almost as large as you phsical memory, but the second usage use the stack momory which is quite scare( normally 8M )
Yes. You can do "temp->link = &node2;", because temp points to node1.
Yes, this rule is very general in C, so it can work for arrays.
When malloc is used, the space is allocated in the heap rather than the stack. This allows you to allocate more space for large data structure. The downside is that you also need to "free" the memory after the usage. Otherwise, memory leak will occur.
If you allocate memory dynamically, you must deallocate that memory programatically by calling free().
In first you are allocating memory dynamically it will allocate the memory from heap. If you store the data in heap memory it will stay until you call free else it will memory will deallocate when program terminate.
your second one store the value in stack its scope is local to the function.
Your example seems that you are working on linked list so you may need to add or delete the node at any time, so using dynamic allocation is the best option.

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