Freeing array of structs inside struct - c

I have two structs
struct obj_t {
int id;
float x;
float y;
};
struct cluster_t {
int size;
int capacity;
struct obj_t *obj;
};
As you can see, there is pointer to first obj_t inside cluster_t
What I want to do is to free every obj_t from array inside cluster_t
Do I have to write it with for loop like this?
void clear_cluster(struct cluster_t *c)
{
for(int i = 0; i<c->size;i++)
{
free(&c->obj[i]);
}
free(c->obj);
}
Or is it ok to free the memory just like this ?
void clear_cluster(struct cluster_t *c)
{
free(c->obj);
}

There should be one free() for every malloc() you have, and executed in the opposite order from which it was allocated.
The field obj of cluster_t is a pointer to an array of object_t. This is probably allocated with one malloc() when initializing your cluster_t (something like c->obj = malloc(c->capacity*sizeof(*c->obj))), so it only needs to be freed with one call to free(). You would then want to free the cluster_t allocation itself (assuming it too was dynamically allocated):
free(c->obj);
free(c);
There would be a difference, however, if each object_t itself had a dynamic allocation within it. (In your example, object_t does not.) In that case, you would have needed to iterate through the array and malloc() an allocation when you created the array, and therefore do the reverse and free() each at the end.

It depends on how you allocated. It seems you did something like
struct cluster_t cluster;
cluster.obj = malloc(sizeof (struct obj_t) * SOMENUMBER);
in this case, cluster.obj is just a pointer to an array. All you need to do is
free(cluster.obj)
or
free(c->obj)
in that function which receives a pointer to c.
You only have to iterate over the array calling free if you have an array of pointers.
Remember that & takes the memory address of the variable. You don't free the pointer, you free the memory that the pointer points to. You will never do something like free(&pointer).

Related

Having trouble allocating memory for my double pointer in structure

I'm trying to allocate memory for a pointer, but have a reference to the address of that pointer. I'm still pretty new to C and this is my first time working with double pointers really.
So I have two structures and they look like this:
typedef struct myNodes {
int data;
struct myNodes *next;
} listElement;
typedef struct {
listElement **ptrToElements;
} myStruct;
In another file, I'm trying to dynamically allocate memory for my pointer by doing something like this:
myStruct *myStruct = malloc(sizeof(*myStruct));
*(myStruct->ptrToElements) = (listElement*)malloc(sizeof(listElement));
but I keep encountering a segmentation fault from doing so. What could be the issue? Thanks!
The problem is with
*(myStruct->ptrToElements) ....
statement. Before dereferencing myStruct->ptrToElements, you need to make sure it points to a valid memory.
To elaborate, you allocate memory for myStruct. Fine.
That constitutes allocating memory for the member ptrToElements. Good.
Question: What does ptrToElements points to?
Answer: Indeterministic.
So, when you try to derefernce a pointer which points to an indeterministic memory address, it's pretty much invalid memory address and attempt to do so will invoke undefined behavior.
Solution: You need to allocate memory for myStruct->ptrToElements before you can go ahead and dereference it.
having said that, please see do I cast the result of malloc?
You define the structure to contain a pointer to a pointer to a listElement
typedef struct {
listElement **ptrToElements;
} myStruct;
As Sourav Ghosh wrote, you try to assign a value to the pointer where ptrToElements would point to without allocating memory.
Probably you should change the pointer type to
typedef struct {
listElement *ptrToElements;
} myStruct;
and when allocating the memory
myStruct *myStruct = malloc(sizeof(*myStruct));
/* If the list can be empty, initialize root with NULL pointer */
myStruct->ptrToElements = NULL;
/* when you add the first list element */
myStruct->ptrToElements = malloc(sizeof(listElement));
myStruct->ptrToElements->data = someValue;
/* at least for the last element you add here you should initialize next */
myStruct->ptrToElements->next = NULL;
Don't forget to handle errors, e.g. malloc returning NULL.
I think this is what you want:
typedef struct myNodes {
int data;
struct myNodes *next; // not clear what this pointer is used for...
} listElement;
typedef struct {
listElement *ptrToElements;
} myStruct;
// Memory Allocation
// allocate myStruct pointing to an array of N listElements
myStruct *ms = malloc(sizeof(myStruct));
ms->ptrToElements = malloc(N * sizeof(listElement));
// element access
for (int i = 0; i < N; i++) {
listElement *le = ms->ptrToElements[i];
le->data = ...
le->next = NULL; // not clear what this pointer is used for...
}
// Memory deallocation
free(ms->ptrToElements);
free(ms);

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);
}

Accessing points inside structs inside unions - C

I have the following data structures
struct a_str {
union {
struct {
struct c_str *c;
} b_str;
struct {
int i;
} c_str;
};
}
struct c_str {
struct d_str;
}
struct d_str {
int num;
}
I am trying to access num in struct d_str. For some reason I keep on getting a segmentation fault.
struct a_str *a = init_a(); //assume memory allocation and init is ok.
a->b_str.c->d_str.num = 2;
What is wrong?
Probably you are not allocating memory for a->b_str.c in your init() function, that may be reason that a->b_str.c is pointing a garbage location and segmentation fault is due to accessing memory that is not allocated - an illegal memory operation.
If init() function is correct, there should not be any problem (syntax-wise your code is correct).
Below I have suggested inti() function that will allocated memory for your nested structure correctly (read comments).
struct a_str *init()
{
struct a_str *ret = malloc(sizeof(struct a_str)); // memory for `struct a_str`
struct c_str *cptr = malloc(sizeof(struct c_str)); // memory for inner struct
ret->b_str.c = cptr; //assigning valid memory address to ret->b_str.c
return ret;
}
Below is the main() code with steps for deallocate/free() dynamically allocated memory.
int main(int argv, char **argc)
{
struct a_str *ret = init();
ret->b_str.c->d.num = 5;
printf("%d\n", ret->b_str.c->d.num);
//Make sure to free the memory allocated through malloc
free(ret->b_str.c); // 1 first free in struct
free(ret); // in reverse order of allocation
return 0;
}
struct a_str *a = init_a();
My guess: Your init_a function
is allocating the a_str pointer
is not allocating the a->b_str.c pointer
Since a->b_str.c is not allocated, when you want to access it, a segfault occur
EDIT :
Second guess: Your init_a function
is allocating the a_str pointer
is allocating the a->b_str.c pointer
is initializing the a->c_str.i integer value
By initializing c_str.i value, it erase the b_str.c value Since it share the same location (it is a union).
you need to check your pointer "c" if it has been initialized

whats wrong in this program?

Am unable to run this code...
#include<cstdio>
int main()
{
struct a{
int b;
struct a *next;
};
typedef struct a no;
no *n;
n->b = 12;
n->next = NULL;
n->next->b = 12;
n->next->next = NULL;
printf("%d %d", n->b, n->next->b);
getchar();
return 0;
}
When you say:
no *n;
you get an uninitialised pointer. When you use that pointer, you get undefined behaviour.
You allocated space for a pointer to a structure, but you didn't allocate space for the actual structure. This means that you don't have a memory address for the structure you are using.
In addition, the pointer points to some random memory address because you didn't initialize it. As a result, you could be trying to read and write to memory that doesn't belong to you, which can cause your program or even your system to crash because of the undefined behavior that results.
As #Neil Butterworth said, you get an uninitialised pointer. This mean that this pointer could point to anywhere, thus giving an access violation error. The way to fix this is simple, just call malloc() before using that pointer. malloc() gives that pointer a valid and usable address, so no one will complain about that.
You're declaring a struct INSIDE a function.
Declare the struct OUTSIDE of the function.
The typedef should be declared outside the function too.
#include<cstdio>
struct a{
int b;
struct a *next;
};
typedef struct a no;
int main()
{
///... your code...
}
try something like this:
no *n = (no*)malloc(sizeof(no));
#include <cstdio>
/* declaring the struct in the function definition may be possible (I'm not sure,
actually, haha). Unless you have a GOOD reason, it's good practice to declare
structs, globals, typedefs, etc... outside the function */
typedef struct a{
int b;
struct a *next;
} no;
int main()
{
no *n;
/* Here, you have a pointer. Remember these are simply (generally) 32-bit values
defined in your stack space used to store a memory location which points to your
ACTUAL struct a! Depending on what USED to be in the stack space, this could
point ANYWHERE in memory, but usually you will find that it points to the NULL
memory location, which is just address "0". To get this to point to something,
you have to allocate empty space on your heap to store your struct... */
n = malloc(sizeof(no));
/* Now your pointer n points to an allocated 'struct a', and you can use it like
normal */
n->b = 12;
n->next = NULL;
/* You just set n->next, which is another 'no' pointer, to NULL. This means that
n->next points nowhere. So, just like above you have to malloc another instance
of the struct! */
n->next = malloc(sizeof(no));
/* NOW you can use n->next with no ill effects! */
n->next->b = 12;
n->next->next = NULL;
printf("%d %d", n->b, n->next->b);
getchar();
/* After you're done with your structs, you want to free them using the POINTERS
that reference them */
free(n->next);
free(n);
return 0;
}

Freeing struct with pointer and non-pointer variables

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).

Resources