简体   繁体   中英

How to free() an array of structs allocated by malloc()?

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!

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.

1.

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.


2.

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM