2017-07-20 12 views
0

Donc, j'essaye d'implémenter un système polymorphique en C, semblable à celui de PyObject et du système objet Python. Cependant, j'ai de la difficulté à comprendre comment une structure d'une structure de base peut être libérée. Je l'ai mis en place la base et types struct avancés:Libère-t-il toute la mémoire d'un pointeur struct plus grand d'un plus petit?

#include "stdio.h" 
#include "stdlib.h" 

//testing for garbage collection 

//base handler to ensure polymorphism 
#define BASE char g; 

struct temp { 
    BASE 
    short w; 
}; 

struct femp { 
    BASE 
    short w; 
    long d; 
}; 


int main(void) { 
    struct femp* first = malloc(sizeof(struct femp)); 
    first->d = 3444; 
    struct temp* second = (struct temp*)first; 
    free(second); // does this deallocate all the memory of first? 
    free(first); 
    return 0; 
} 

Note: Le programme ci-dessus se termine avec le statut non nul si la deuxième est libéré, mais pas d'abord.

Résultat:

7fb829d02000-7fb829d04000 rw-p 00000000 00:00 0 
7fb829d0c000-7fb829d10000 rw-p 00000000 00:00 0 
7fb829d10000-7fb829d11000 r--p 00023000 00:136 38      /usr/lib/x86_64-linux-gnu/ld-2.24.so 
7fb829d11000-7fb829d12000 rw-p 00024000 00:136 38      /usr/lib/x86_64-linux-gnu/ld-2.24.so 
7fb829d12000-7fb829d13000 rw-p 00000000 00:00 0 
7fffac407000-7fffac428000 rw-p 00000000 00:00 0       [stack] 
7fffac499000-7fffac49b000 r--p 00000000 00:00 0       [vvar] 
7fffac49b000-7fffac49d000 r-xp 00000000 00:00 0       [vdso] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
exited with non-zero status 

Ma question est, n'appelle free() sur un pointeur vers une structure plus petite taille, qui est casté d'une struct plus grande taille malloc'd originale, toujours libre toute la mémoire? comme dans mon code, y a-t-il une différence entre libérer en premier ou en second? Devriez-vous toujours revenir au type d'origine avant de libérer?

+1

Vous ne "allouez pas de structures", vous allouez des quantités de mémoire. Malloc prend un argument entier qui est un nombre d'octets. Free libère juste de nombreux octets. Ni l'un ni l'autre ne sait rien sur les structures. –

+0

'free' prend un pointeur sur' void'. Donc ça ne se soucie vraiment pas de ce à quoi il a été moulé auparavant. –

+0

ok, donc cela signifierait que vous devez libérer() quelle structure de taille était initialement malloc'd alors? correct? –

Répondre

3

malloc()/free() ne connaissez absolument rien à vos structures. malloc() prend un argument entier et alloue autant d'octets, vous donnant une adresse mémoire. free() prend cette adresse et libère tout ce qui a été alloué. Ce que vous en faites en attendant dépend de vous.

Si vous avez besoin d'un peu de mémoire pouvant contenir deux choses, c'est à vous de vous assurer qu'il est suffisamment grand. Si vous allouez un seau de 5 gallons et que vous l'utilisez seulement pour transporter 3 gallons, c'est bien. Si vous essayez de transporter 7 gallons, vous aurez vos pieds mouillés. C ne vous interférera pas non plus.

+0

ok cela est logique, mais pourquoi dans ce cas libérant le pointeur sur une structure plus petite provoque un statut non nul? –

+2

Parce que vous libérez la même adresse deux fois. –