2016-12-03 1 views
0

J'ai deux structtableau Libérant de struct dans struct

struct obj_t { 
    int id; 
    float x; 
    float y; 
}; 

struct cluster_t { 
    int size; 
    int capacity; 
    struct obj_t *obj; 
}; 

Comme vous pouvez le voir, il y a pointeur d'abord obj_t à l'intérieur cluster_t

Ce que je veux faire est de libérer tous les obj_t de tableau à l'intérieur cluster_t

Dois-je l'écrire avec for comme ceci?

void clear_cluster(struct cluster_t *c) 
{ 
    for(int i = 0; i<c->size;i++) 
    { 
     free(&c->obj[i]); 
    } 
    free(c->obj); 
} 

Ou est-il correct de libérer la mémoire juste comme ceci?

void clear_cluster(struct cluster_t *c) 
{ 
    free(c->obj); 
} 
+1

Au verso de la séquence où vous avez affecté. –

+1

* "Comme vous pouvez le voir, le tableau de' obj_t' se trouve dans 'cluster_t'" "- je ne vois aucun tableau dans' cluster_t'. Je peux voir un pointeur mais c'est une chose différente. – axiac

+0

Il n'y a pas non plus de pointeur sur array dans votre 'struct'! – Olaf

Répondre

3

Il doit y avoir un free() pour chaque malloc() que vous avez et exécuté dans l'ordre inverse à partir duquel il a été alloué.

Le champ obj de cluster_t est un pointeur sur un tableau de object_t. Cela est probablement alloué avec un malloc() lors de l'initialisation de votre cluster_t (quelque chose comme c->obj = malloc(c->capacity*sizeof(*c->obj))), donc il doit seulement être libéré avec un appel à free(). Alors vous voulez libérer l'allocation elle-même cluster_t (en supposant qu'il était trop affecté dynamiquement):

free(c->obj); 
free(c); 

Il y aurait une différence, cependant, si chaqueobject_t avait lui-même une allocation dynamique en son sein. (Dans votre exemple, object_t ne fait pas.) Dans ce cas, vous auriez dû parcourir le tableau et malloc() une allocation lorsque vous avez créé le tableau, et donc faire l'inverse et free() chacun à la fin.

+1

@HynekBernard la 'struct cluster_t' a aussi des membres' int size' et 'int capacity' qui suggèrent que la mémoire allouée au membre' struct obj_t * obj' pourrait être étendue avec 'realloc()' une ou plusieurs fois. Cela compte comme une allocation unique et n'a besoin que d'un "gratuit". –

2

Cela dépend de la façon dont vous avez affecté. Il semble que vous avez fait quelque chose comme

struct cluster_t cluster; 
cluster.obj = malloc(sizeof (struct obj_t) * SOMENUMBER); 

dans ce cas, cluster.obj est juste un pointeur vers un tableau. Tout ce que vous devez faire est

free(cluster.obj) 

ou

free(c->obj) 

dans cette fonction qui reçoit un pointeur vers c.

Vous devez parcourir uniquement le tableau appelant free si vous disposez d'un tableau de pointeurs.

Rappelez-vous que & prend l'adresse mémoire de la variable. Vous ne libérez pas le pointeur, vous libérez la mémoire vers laquelle pointe le pointeur. Vous ne ferez jamais quelque chose comme free(&pointer).