Allocation and memory cleaning in C - how much should I care?

2

I am learning C from the book "Use the Head! C" (condemn me). Given a lesson, I need to create a struct called " island " with the following code:

typedef struct island {
    const char *name;
    const char *opens;
    const char *closes;
    struct island *next;
} island;

After a series of changes I follow in the book, it is time to write a method to create a island , allocating memory dynamically with malloc to return the pointer of the created object. Here is the code for this function:

island* create(char *name)
{
    island *i = malloc(sizeof(island));
    i->name = strdup(name);
    i->opens = "09:00";
    i->closes = "17:00";
    i->next = NULL;

   return i;
}

Finally, and where is my problem, the book guides you to free the memory that you have allocated so you do not leave it with "garbage", using a release method:

void release(island *start)
{
    island *i = start;
    island *next = NULL;
    for(; i != NULL; i = next) {
        next = i->next;
        free(i->name);
        free(i);
    }
}

When trying to pass a struct to this function, I get the following errors:

memoriaDinamica.c: In function ‘release’:
memoriaDinamica.c:83:14: warning: passing argument 1 of ‘free’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
         free(i->name);
              ^
In file included from memoriaDinamica.c:2:0:
/usr/include/stdlib.h:483:13: note: expected ‘void *’ but argument is of type ‘const char *’
 extern void free (void *__ptr) __THROW;
             ^
*** Error in './memoriaDinamica': free(): invalid pointer: 0x0000000000400940 ***
Name: Amity open: 09:00-17:00
Name: Craggy open: 09:00-17:00
Name: Isla Nublar open: 09:00-17:00
Name: Skull open: 09:00-17:00

The newly created island:
Name: Hawaii open: 09:00-17:00
Name: Skull open: 09:00-17:00
======= Backtrace: =========
/lib64/libc.so.6(+0x77a8d)[0x7fee806c1a8d]
/lib64/libc.so.6(cfree+0x5cd)[0x7fee806cdd2d]
./memoriaDinamica[0x400886]
./memoriaDinamica[0x400791]
/lib64/libc.so.6(__libc_start_main+0xf0)[0x7fee8066a700]
./memoriaDinamica[0x400589]
======= Memory map: ========
00400000-00401000 r-xp 00000000 fd:02 2097225                            memoria-dinamica/memoriaDinamica
00600000-00601000 r--p 00000000 fd:02 2097225                            memoria-dinamica/memoriaDinamica
00601000-00602000 rw-p 00001000 fd:02 2097225                            memoria-dinamica/memoriaDinamica
02248000-02269000 rw-p 00000000 00:00 0                                  [heap]
7fee80433000-7fee80449000 r-xp 00000000 fd:01 1049963                    /usr/lib64/libgcc_s-5.1.1-20150618.so.1
7fee80449000-7fee80648000 ---p 00016000 fd:01 1049963                    /usr/lib64/libgcc_s-5.1.1-20150618.so.1
7fee80648000-7fee80649000 r--p 00015000 fd:01 1049963                    /usr/lib64/libgcc_s-5.1.1-20150618.so.1
7fee80649000-7fee8064a000 rw-p 00016000 fd:01 1049963                    /usr/lib64/libgcc_s-5.1.1-20150618.so.1
7fee8064a000-7fee80801000 r-xp 00000000 fd:01 1054187                    /usr/lib64/libc-2.21.so
7fee80801000-7fee80a00000 ---p 001b7000 fd:01 1054187                    /usr/lib64/libc-2.21.so
7fee80a00000-7fee80a04000 r--p 001b6000 fd:01 1054187                    /usr/lib64/libc-2.21.so
7fee80a04000-7fee80a06000 rw-p 001ba000 fd:01 1054187                    /usr/lib64/libc-2.21.so
7fee80a06000-7fee80a0a000 rw-p 00000000 00:00 0 
7fee80a0a000-7fee80a2b000 r-xp 00000000 fd:01 1054235                    /usr/lib64/ld-2.21.so
7fee80c05000-7fee80c08000 rw-p 00000000 00:00 0 
7fee80c27000-7fee80c2a000 rw-p 00000000 00:00 0 
7fee80c2a000-7fee80c2b000 r--p 00020000 fd:01 1054235                    /usr/lib64/ld-2.21.so
7fee80c2b000-7fee80c2c000 rw-p 00021000 fd:01 1054235                    /usr/lib64/ld-2.21.so
7fee80c2c000-7fee80c2d000 rw-p 00000000 00:00 0 
7ffc4d52b000-7ffc4d54c000 rw-p 00000000 00:00 0                          [stack]
7ffc4d550000-7ffc4d552000 r--p 00000000 00:00 0                          [vvar]
7ffc4d552000-7ffc4d554000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
/bin/sh: line 1: 23871 Abortado                (imagem do núcleo gravada)./memoriaDinamica

I understand that a reference to a constant can not be freed for obvious reasons, so should I really care about cleaning up that allocated memory in cases like this one?

Pastebin Full Code

    
asked by anonymous 03.11.2015 / 00:18

1 answer

1

You should be concerned since the strdup() (would be better to use strndup() ) allocates memory in the heap . All memory allocated in the heap should be freed.

C does not have garbage collector , and all memory management must be done manually. Of course you can create some functions to help, but as you are sophisticated and automating, you are creating some kind of GC for your application.

Some functions can do a little this kind of service. This is the case of strndupa() . It is not standardized and therefore not portable. It does not solve all situations.

The solution is to take const , after all something that will be allocated in heap is not constant.

If you want to insist on this, do a cast :

free((char *)i.name);

or

free((void *)i.name);

I will not guarantee that it works with all compile options. Then the solution would be to turn off warning , which I do not recommend.

    
03.11.2015 / 01:05