C - libérer les structures
Disons que j'ai cette structure
typedef struct person{
char firstName[100], surName[51]
} PERSON;
et je suis d'allouer de l'espace par malloc et de le remplir avec certaines valeurs
PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));
strcpy(testPerson->firstName, "Jack");
strcpy(testPerson->surName, "Daniels");
Ce qui est correct et sûr moyen de libérer toute la mémoire prise par cette structure? Est "gratuit(testPerson);" suffisant ou dois-je libre de chaque structure de l'attribut, un par un?
Il me conduit à une autre question - comment sont les structures stockées dans la mémoire? J'ai remarqué un comportement étrange - lorsque j'essaie d'imprimer la structure de l'adresse c'est égal, c'est le premier attribut de l'adresse.
printf("Structure address %d == firstName address %d", testPerson, testPerson->firstName);
Ce qui signifie que ce
gratuit(testPerson)
doit être égal à ce
gratuit(testPerson->prenom);
et ce n'est pas ce que je veux faire.
Grâce
- Une bonne règle de base: pour chaque malloc vous avez besoin exactement libres (pas plus, pas moins).
Vous devez vous connecter pour publier un commentaire.
Réponse Simple :
free(testPerson)
est assez .Oubliez pas que vous pouvez utiliser
free()
seulement quand vous avez la mémoire allouée à l'aide demalloc
,calloc
ourealloc
.Dans votre cas, vous n'avez qu'malloced mémoire pour
testPerson
afin de libérer c'est suffisant.Si vous avez utilisé
char * firstname , *last surName
alors dans ce cas, au nom de la banque, vous devez avoir la mémoire allouée et c'est pourquoi vous avez dû le libérer chacun de ses membres individuellement.Ici est également un point qu'il devrait être dans l'ordre inverse, c'est à dire, la mémoire allouée pour les éléments est faite plus tard donc
free()
d'abord puis libérer le pointeur vers l'objet.Libérant chaque élément, vous pouvez voir la démo présentée ci-dessous:
La raison derrière cela est, si vous libérer de l'
ptrobj
d'abord, puis il y aura la mémoire de fuite qui est la mémoire allouée parfirstname
etsuName
pointeurs.free(ptrobj)
est fait, alorsfirstname
etsuname
les pointeurs sont des membres sur le tas qui est allé , de sorte que la mémoire allouée parfirstname
etsuname
ne seront pas libérés, car gratuit, il vous faudra écrirefree(firstname)
mais le prénom n'existent plus ..hopw vous l'avez obtenuCar vous avez défini le
struct
composé dechar
tableaux, les deux chaînes sont la structure et de la libération de lastruct
est suffisante, ni est-il un moyen de libérer lastruct
mais gardez les tableaux. Pour qui vous voulez faire quelque chose commestruct { char *firstName, *lastName; }
, mais alors vous avez besoin d'allouer de la mémoire pour les noms séparément et de répondre à la question de quand gratuit que mémoire.De côté: Est-il un raison vous souhaitez conserver les noms après la
struct
a été libéré?alloc
famille de fonctions utilisation de la comptabilité, ce qui signifie que les caractères qui composent vos chaînes de rester dans la mémoire jusqu'à ce qu'ils soient remplacés, mais vous avez appeléfree
(1) il est formellement incorrect de l'accès que de la mémoire à nouveau (à moins que plus tard allocation réutilise) et (2) vous n'avez pas de garantie de ce qui est là.Abord, vous devez savoir, combien la mémoire est allouée lorsque vous définir et allouer de la mémoire dans les cas ci-dessous.
1) La sizeof(PERSONNE) retourne maintenant 151 octets (Ne pas inclure rembourrage)
2) La mémoire de 151 octets est alloué dans le tas.
3) gratuit, appel gratuit(testPerson).
mais Si vous déclarez votre structure
puis
1) La sizeof(PERSONNE) retourne maintenant 8 octets (Ne pas inclure rembourrage)
2) le Besoin d'allouer de la mémoire pour les prénom et nom de famille en appelant la fonction malloc() ou calloc(). comme
3) Pour gratuite, gratuit les membres de la struct que la gratuité de la struct. j'.e,
gratuit(testPerson->prenom);
gratuit(testPerson->nom);
gratuit(testPerson);
De cette façon, vous avez seulement besoin de libérer de la structure car les champs sont des tableaux statiques de tailles qui seront alloués dans le cadre de la structure. C'est aussi la raison pour laquelle les adresses que vous voir le match: le tableau est la première chose à cette structure. Si vous avez déclaré les champs de type char * vous devez manuellement malloc et free ainsi.
Mallocs et libère besoin d'être jumelé.
malloc a saisi une partie de la mémoire assez grande pour une Personne.
Lorsque vous libre de vous dire malloc l'élément de mémoire de départ "ici" n'est plus nécessaire, il sait combien il alloués et la libère.
Si vous appelez
ou
tous que free() reçoit réellement est une adresse, même adresse, il ne peut pas dire ce qui vous a appelé. Votre code est beaucoup plus clair si vous utilisez libre(testPerson) bien qu'il correspond clairement à la avec malloc.
free(testPerson->firstName)
est source de confusion pour les débutants, quant à pourquoi il fonctionne.Vous ne pouvez pas libérer types qui ne sont pas attribuées de manière dynamique. Bien que les tableaux sont syntaxiquement similaire (
int* x = malloc(sizeof(int) * 4)
peut être utilisé de la même manière queint x[4]
est), l'appel defree(firstName)
serait susceptible de provoquer une erreur pour le dernier.Par exemple, prenez ce code:
free()
est une fonction qui prend un pointeur.&x
est un pointeur. Ce code peut compiler, même si elle ne fonctionnerait tout simplement pas.Si nous prétendons que toute la mémoire est allouée dans la même façon,
x
est "affecté à la définition, "libéré" à la deuxième ligne, puis de "libéré" de nouveau après la fin de la portée. Vous ne pouvez pas libérer la même ressource en deux fois; il va vous donner une erreur.Ce n'est même pas mentionner le fait que, pour certaines raisons, vous avez peut-être pas en mesure de libérer la mémoire à
x
sans fermer le programme.tl;dr: il suffit de libérer le
struct
et vous serez amende. Ne pas appel gratuit sur les tableaux; appeler uniquement sur la mémoire allouée dynamiquement.free(&x)
peut-être déjà l'échec.free
n'est pas assez,free
marque simplement la mémoire inutilisée, la structure de données sera là jusqu'à l'écrasement. Pour plus de sécurité, définir le pointeur àNULL
aprèsfree
.Ex:
struct
est semblable à un tableau, c'est un bloc de mémoire. Vous pouvez accéder à struct membre par l'intermédiaire de son décalage. La première structure est membre est placé au décalage0
l'adresse de la première struct membre est la même que l'adresse de struct.