Freeing struct with pointer and non-pointer variables - c

I'm trying to implement linked-lists with c struct, I use malloc to allocate a new node then allocate space for value, so I've been thinking how to free the structure once I'm done with them, my structure looks like this:
typedef struct llist {
char *value;
int line;
struct llist *next;
} List;
I have a function that walks through the struct and free its members like this:
free(s->value);
free(s);
My question is, does that also free the int line?

Yes.
The int line is part of the structure, and so gets freed when you free the structure. The same is true of the char *value. However, this does not free the memory which value points at, which is why you need to call free separately for that.

Yes it does. When you allocated memory for s it allocated memory for these three:
pointer to a char (value)
integer (line)
pointer to a struct llist (next)
When you freed s, all that storage went away (which includes memory for line).

Related

How to free char array in struct

I see that you can free char * pointers within struct but how do you free char[N] inside a struct
typedef struct Edge
{
char number[13];
int numOfCalls;
struct Edge *next;
} Edge;
When I do this i get an error
Edge *edge = malloc(sizeof(Edge));
edge->next = NULL;
strcpy(edge->number,numberOne); // numberOne is also a char[13];
free(edge->number);
free(edge);
If you use char array (char number[13]) in struct, you don't have to malloc or free the array. Once you do malloc for struct Edge, there is also space for number in memory.
In summary, if you use char pointer as a member of struct Edge, you need to malloc or free memory space for char pointer, but you don't have to do that in your case. Therefore, delete free(edge->number) line.
The lifespan of number in the struct Edge is automatic. Even if you dynamically allocate an Edge struct, when you free the struct, you'll free the memory for the char array.

Is freeing a dynamically allocated array same as freeing a linked list?

Suppose I have a struct that looks like this:
typedef struct node{
char **word_ptrs;
int value;
struct node *next;
} Node;
and I have dynamically allocated spaces for the linked list, as well as the word_ptrs within this struct.
For example:
Node *head = malloc(sizeof(Node)); // not important, what I care is not this node.
head->word_ptrs = malloc(10 * sizeof(Node)); // I care about this.
My question is: I know how to free the linked list, but I feel confused when I try to free the dynamically allocated array. When I try to free the array above, should I just directly free the entire array? Or I should go to free every single char * within that array?
Thanks.
You should only pass to free what was returned from malloc.
In this case, you make one allocation for an array of char *, so you do a single free to clean it up. Also, the amount of space you're allocating is 10 * sizeof(Node), but it should be 10 * sizeof(char *).
That depends on where those pointers came from, and who owns them.
If they were dynamically allocated and the node owns them, then you should free them before freeing the array.
If they were dynamically allocated but owned elsewhere, their respective owners should free them later.
If they were not dynamically allocated, you mustn't free them at all.
If you have a combination of the three, you're in trouble.
You should also allocate it with sizeof(char*), or sizeof(*head->word_ptrs), not sizeof(Node).
Although, if the size is always ten, you might as well use an array:
typedef struct node{
char *word_ptrs[10];
int value;
struct node *next;
} Node;

Does the struct get freed this way in C?

I have the following struct which I use to implement a priority queue
struct q_element
{
//Declaration of struct members
int element;
int priority;
struct q_element *next_element;
};
and I use a pointer to a struct 'cur' to start from the first item in the queue
struct q_element* cur = start_element;
and keep moving until I find the one I want to delete from list.
while (cur->priority!=max_priority)
cur = cur->next_element;
Does the following line of code actually free the struct? Because 'cur' is a pointer to the struct I wasn't completely sure.
free(cur);
You need to pass a pointer to free, so free(cur) is the way to go, assuming that the struct itself has been allocated using malloc/calloc/realloc. Specifically, if you allocated your curr in the automatic memory (i.e. on the stack) you are not supposed to call free on it.
It looks like q_element is part of a linked list. Freeing the struct itself will not free other structs pointed to by it, so if you'd like to free the struct along with its tail, you need to write a loop.
Finally, when you free memory pointed to by some pointer in your program, it is a very good idea to assign NULL to the pointer that you freed to avoid accidental double-freeing and undefined behavior on accessing freed memory.

C - What is wrong with my memory freeing function?

I have a struct which contains 2 integers and a pointer to another struct. I allocate memory for struct first and then for the pointer. When I free the memory I free up the pointer first and then I free up the struct.
When I run my program and call the function that frees memory it crashes when the call is made. When I don't call the function that frees memory it works fine, but then I'm not freeing up the memory.
I tried removing the line that frees the memory allocated to the pointer and the program doesn't crash, but I don't think thats right since a "free" is needed for every "malloc/calloc" right? Anyone see anything wrong with the freeing function?
//Define a struct data type
struct q_element
{
//Declaration of struct members
int element;
int priority;
struct q_element *next_element;
};
//Method to allocate memory
struct q_element* allocateStruct()
{
//Declaration of a variable
struct q_element *e;
//Allocate memory for one queue element
e = malloc(sizeof(struct q_element));
//Allocate memory for one pointer to a queue element
e->next_element = calloc(1,sizeof(struct q_element*));
//Initialize integer members of queue element
e->element = 0;
e->priority = 0;
return e;
}
//Method to free memory allocated
void freeStruct(struct q_element* e)
{
//Free up pointer member
free(e->next_element);
//Free up struct
free(e);
}
You don't need to allocate memory for the next_element pointer. The pointer is already there, just like int element for example.
So if you want to allocate just one element, you can set the next_element pointer to NULL and everything is fine.
You are not allocating enough memory for e->next_element in the line:
e->next_element = calloc(1,sizeof(struct q_element*));
// ^^^ remove the *
That should be:
e->next_element = calloc(1,sizeof(struct q_element));
If you used e->next_element as though it were a valid pointer, you most likely ended up accessing memory that you did not allocate. That clobbered some of the bookkeeping information created by calloc, which lead to problems when you called free.
In
//Allocate memory for one pointer to a queue element
e->next_element = calloc(1,sizeof(struct q_element*));
you allocate space for a pointer to a q_element structure, rather than a q_element structure. Do you attempt to write to this structure, because if so, that's probably where it goes wrong.
As a side note you might be better off just doing
e->next_element = 0
inside allocate_struct and then doing e->next_element = allocate_struct() outside the function later.
In addition to what everyone else is mentioning about allocation, you also need a sentinel to check if the next_element was already freed. You may be attempting a double free.
Try the following code:
void freeStruct(struct q_element* e)
{
//Free up pointer member
if(e->next_element != 0){
free(e->next_element);
e->next_element = 0;
}
//Free up struct
free(e);
}

How can I free up n bytes of memory in C?

I wanted to create a generic Linked List in C. Following is the structure of the node:
typedef struct node {
void *value;
int size; // n bytes
ind index; // index of the node
struct node *next;
} Node;
And my delete_node function is as following. The search function sends a pointer to the Node I want to delete.
Node *search_list(Node *list, void *data, int n_bytes);
int delete_node(Node *list, Node *to_be_deleted); // returns 1 on success
Inside the delete_node function I want to free up the memory pointed by void *value and then free up the memory allocated for the Node itself.
free(to_be_deleted->value); // Would this work??
free(to_be_deleted);
Since it is void pointer we don't know that how many bytes the object it is pointing to has occupied. How can we free up the memory for that?
Sorry if it is a stupid questions?
The memory allocator keeps track of how large memory allocations are on its own -- there's no need to tell free() how much memory to free.
As such, you should be able to just get rid of size and n_bits.
free(to_be_deleted->value); // Would this work??
Straight forward answer , Yes this will work.
simple thing :
see the definitions of free() and malloc()
void free(void *) // free takes void* as argument so it will work
void* malloc(sizeof(type))
In mallocwe have to pass thesize that how many bytes we want to allocate.
but in free just pass the pointer and whatever bytes allocated to that pointer on heap storage it will be freed
Yes, what you wrote should work. The reason is that malloc (which is a library call) creates metadata that is used to determine which parts of memory are free and which ones are taken. When you call free(), you are actually only modifying this metadata such that subsequent calls to malloc know that this memory can be re-used (note that most implementations will not zero the existing data).

Resources