Considérez le code C:
void mycode() { MyType* p = malloc(sizeof(MyType)); /* set the values for p and do some stuff with it */ cleanup(p); } void cleanup(MyType* pointer) { free(pointer); pointer = NULL; }
6 Réponses :
oui qui libérera la mémoire correctement.
Ceci pourrait ajouter à votre confusion, mais vous pouvez ajuster la valeur de la variable Dans ce cas, Je remarquerai qu'il est généralement une bonne pratique de faire face à l'allocation et à la répartition du même «niveau» logique du logiciel - c'est-à-dire que Don ' t Faites-vous la responsabilité des appelants de répartir la mémoire, puis de libérer les fonctions intérieures. Conservez-le cohérent et au même niveau. P> p> pointeur code> à l'intérieur de la fonction de nettoyage est une variable locale; Une copie de la valeur passée dans les stockages stockés localement pour une seule fonction. p>
p code> du
à partir du
MyCode code> Méthode, comme: p>
pointeur code> stocke l'adresse du pointeur. Par la déséroférience que, vous pouvez modifier la valeur stockée à cette adresse. P>
Vous manquez de dire que cet appel doit être Nettoyage (& P); Code>
et appelez-le comme: p> Votre code est un peu non idiomatique, pouvez-vous expliquer un peu mieux pourquoi vous souhaitez écrire ce Nettoyage code> sera correctement libéré
p code>, mais cela ne changera pas sa valeur. C est une langue de valeur transparente, vous ne pouvez donc pas modifier la variable de l'appelant de la fonction appelée. Si vous souhaitez définir
p code> de
nettoyer code>, vous devez faire quelque chose comme:
Nettoyage code> Fonction? P> < / p>
oui fort> p>
oui fort> p>
oui: strong> Il existe un bloc de mémoire produit par magie par Ensuite, vous passez BACK IN Vous remarquerez peut-être que vous pouvez même stocker encore et lire à partir de La lecture attentive sur C peut vous donner une idée abstraite de la durée de vie variable, mais il est beaucoup plus facile de visualiser la mise en œuvre de la mise en œuvre de la répartition des paramètres et de la variable locale comme opérations de pile. Il est utile de suivre un cours d'assemblage avant le cours C. P> MALLOC code> (3). Vous avez attribué l'adresse de cette mémoire, mais pas la mémoire elle-même de manière significative, au pointeur
p code> qui est une variable code> auto code> dans
mycode () < / code>. p>
p code> à
nettoyer () code>, par valeur, qui copiera le pointeur et, à l'aide de la copie locale sur
Nettoyage () code>, libérer le bloc.
Nettoyage () Code> Définit ensuite la propre instance du pointeur sur NULL, mais cela est inutile. Une fois la fonction remplie, le paramètre
pointeur code> cesse d'exister. P>
MYCODE () CODE>, vous avez toujours le pointeur
p code> Tenir une adresse, mais le bloc est maintenant sur la liste gratuite et n'est pas terriblement utile pour le stockage jusqu'à ce qu'il soit à nouveau alloué . p>
* p, code> mais diverses quantités de perte en aval se produiront, car ce bloc de mémoire appartient maintenant à la bibliothèque et vous pouvez corrompre ses structures de données ou les données d'un futur propriétaire d'un bloc Malloc (). P>
Hehehe ... Non, j'étais sérieux. En fait, j'ai commencé une longue réponse, mais j'ai décidé de le laisser tomber, car il s'agissait davantage de savoir comment l'enseignement de la programmation est passée de bas en haut (le meilleur moyen d'imo) de haut en bas (cela ne fonctionne pas bien, fondamentalement parce que n'est pas un sommet) à recharger (c.-à-d. Partir de laid de choses comme Java et d'aller nulle part). Je crois vraiment que les pointeurs sont morts simples, mais seulement si vous avez une saisie ferme de la façon dont un ordinateur fonctionne (un assemblage simple est un bon point de départ). Sans cette programmation de base devient juste un énorme tas de mots magiques avec des propriétés étranges.
@ 6502: Je suis totalement d'accord - le "Guide de l'utilisateur" pour le C64 était génial.
@ 6502, bien sûr, de bons points. Mais ce que j'ai "obtenu" était votre nom d'utilisateur. Bon choix.
Ceci ne fonctionnera pas comme le pointeur code> dans code> dans Nettoyage () code> est local et l'attribuant ainsi
null code> n'est pas vu par l'appelant fonction. Il y a deux façons courantes de résoudre ce problème.
Nettoyage () code> comme suit: li>
ol>
void cleanup(MyType** pointer)
{
free(*pointer);
*pointer = NULL;
}
Il y a deux questions sont ici: p>
je me trompe en pensant qu'après nettoyage (p); est appelé, le contenu de p devrait maintenant être nul? p> blockQuote>
Oui, c'est faux. Après avoir appelé
gratuit code> la mémoire pointée par le pointeur est compensée. Cela ne signifie pas que le contenu pointé par le pointeur est réglé sur NULL. En outre, si vous attendez que le pointeur
p code> devienne null dans
mycode code> Cela ne se produit pas parce que vous passez copie em> de
p code> à
Nettoyage code>. Si vous voulez
p code> pour être null dans
mycode code>, vous avez besoin d'un pointeur sur le pointeur dans
Nettoyage code>, c'est-à-dire la signature de nettoyage serait
Nettoyage (mytype **) code>. p>
Deuxième question: P>
nettoyage (mytype * pointeur) correctement Gratuit l'allocation de mémoire? P> blockQuote>
Oui, puisque vous faites
gratuit code> sur un pointeur renvoyé par
malloc code> la mémoire sera libérée. p>
Ce n'est pas juste vous.
Il y a trois façons autour de ceci: p> Utilisez un pointeur sur un pointeur. P>
Utilisez une macro. P>
Nettoyage () code> va bien nettoyer votre allocation, mais ne définira pas le pointeur sur
null code> (qui devrait être considéré comme étant Séparez du nettoyage.) Les Data Les points de pointeur sur em> sont transmis à
nettoyer () code> par pointeur et sont
libres () code> ed correctement, mais le pointeur lui-même em> est passé par valeur, alors lorsque vous l'avez défini sur
null code> Vous n'affectant que la copie locale
(code> de la fonction de la fonction Pointeur, pas le pointeur d'origine. P>
void cleanup_func(struct MyType *p) { /* more complicated cleanup */ }
#define cleanup(p) do { cleanup_func(p); p = NULL; } while(0)