Reputation: 45
I've been working on a project that uses structs as storage for strings. I declared a struct consists of char type members:
struct datastore1
{
char name[50];
char address[50];
char email[50];
char number[50];
char idnum[50];
};
I'm aware that I can just do char *name, char *address...
but let's say we specified it with max length of 50. Then on my function which uses the struct, I malloc'ed it with index size of 30:
struct datastore1 *dsdata = malloc(30 * sizeof(struct datastore1));
Supposedly I finished copying all strings into the struct by accessing each index, How should i free the allocated memory that was used after calling malloc? I tried doing free(dsdata)
on the end of the program but I am not sure if it's the right way. Should i free each indexes individually? Please enlighten me. Thank you in advance for the feedback!
Upvotes: 3
Views: 2876
Reputation: 1579
How should i free the allocated memory that was used after calling malloc?
Consider below example,
struct datastore1 *obj1 = malloc(sizeof(struct datastore1));
free(obj1);
Here obj1
is pointing to the block of memory of size same as size of datastore1
in order to free you need to send the address which is allocated by malloc
.
likewise,
struct datastore1 *obj2 = malloc(3 * sizeof(struct datastore1));
free(obj2);
obj2
is pointing to a block of contiguous memory of size 3 * sizeof(datastore1)
you need to pass the base address to free
Should i free each indexes individually?
NO, Since block of memory is allocated only once and you need to free
exactly one time.
Let me extend it further,
struct datastore1 *obj3[3];
for(int i=0;i<3;i++)
obj3[i] = malloc(sizeof(struct datastore1));
for(int i=0;i<3;i++)
free(obj3[i]);
Here obj3
is array of pointer and each index is pointing to different part of memory and hence need to be freed individually.
Note: For simplicity I haven't considered return value from malloc
. Null check has to be done on malloc
return value.
Upvotes: 6
Reputation: 15042
How should I free the allocated memory that was used after calling malloc?
I tried doing
free(dsdata)
on the end of the program but I am not sure if it's the right way.
free(dsdata)
is fine, since you allocated the whole space by just one call to malloc
with:
struct datastore1 *dsdata = malloc(30 * sizeof(struct datastore1));
To cite the standard (C18), 7.22.3.4 - "The malloc function" (emphasize mine):
7.22.3.4 The malloc function
Synopsis
1
#include <stdlib.h> void* malloc(size_t size);
Description
2 The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.
Returns
3 The malloc function returns either a null pointer or a pointer to the allocated space.
It is correct to use free(dsdata)
because malloc
allocated all of the required space at once and returned a pointer to the first structure variable of this array which is assigned to the pointer of dsdata
.
The free()
function "knows" that dsdata
is a reference to the whole allocated space. You do not need to free each of the 30 structures of type struct datastore1
in memory individually.
Should I free each indexes individually?
No, you do not need and even more important you should not do so; this would be Undefined Behavior:
Citation from the current standard (C18), 7.22.3.5/3 - "The free function" (emphasize mine):
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.
Upvotes: 1
Reputation: 156
Both answers above are correct, but to fully understand how does it work I recommend you to learn how to use valgrind
.
To check if program released memory correctly use
valgrind -v --leak-check=full --track-origins=yes ./your-program
This will execute your program on valgrind's virtual processor and give you full feedback about used resources.
Basically operator []
in C programming language in array definition context causes creation of (lets say to simplify) static array - this means that array is included in size of structure (if defined as part of structure) or is stored on the stack (if defined in function or globally).
The malloc
function returns address of block of data you can use. Size of this block is at least as big as you requested. When you use free
you release this block wich in this case means all data in block pointed by this address will be released.
Upvotes: 0
Reputation: 4288
As far as I understand you only used malloc
to allocate space for an array of datastore1
struct, so it is sufficient to just do free(dsdata)
.
If in the struct you would have pointers and you would use malloc
to allocate each of them, only than you would need to free
each of them first.
Upvotes: 0