La mémoire allouée avec malloc ne persiste pas en dehors de la scope de la fonction?

Salut,

Je suis un peu nouveau dans la fonction malloc de C, mais d’après ce que je sais, il convient de stocker la valeur dans le tas, afin que vous puissiez la référencer avec un pointeur situé en dehors de la scope d’origine. J’ai créé un programme de test censé le faire, mais je continue à obtenir la valeur 0 après avoir exécuté le programme. Qu’est-ce que je fais mal?

int f1(int * b) { b = malloc(sizeof(int)); *b = 5; } int main() { int * a; f1(a); printf("%d\n", a); return 0; } 

Oui! a est passé par valeur pour que le pointeur b de la fonction f1 soit local .. soit retourne b ,

 int *f1() { int * b = malloc(sizeof(int)); *b = 5; return b; } int main() { int * a; a = f1(); printf("%d\n", *a); // keep it clean : free(a); return 0; } 

ou passer l’adresse d’un

 int f1(int ** b) { *b = malloc(sizeof(int)); **b = 5; } int main() { int * a; f1(&a); printf("%d\n", *a); // keep it clean : free(a); return 0; } 

On dirait que vous comprenez mal une partie fondamentale du fonctionnement de C, à savoir qu’il s’agit d’un langage de type «passage par valeur». Pour que main() connaisse la mémoire que vous avez allouée, vous devez la récupérer. Le code suivant vous fera ce que vous voulez:

 int f1(int **b) { *b = malloc(sizeof(int)); **b = 5; } int main(int argc, char **argv) { int *a; f1(&a); printf("%d\n", *a); return 0; } 

Il y a quelques différences entre ce code et le vôtre; f1() abord, la signature de f1() a été modifiée afin de pouvoir renvoyer le résultat de l’appel de malloc() dans le pointeur transmis. Ensuite, l’appel à f1() a été modifié pour transmettre l’adresse d’ a plutôt que de lui-même – important si vous voulez qu’il soit “rempli” par f1() , pour ainsi dire. Enfin, printf() dans main() a été modifié pour afficher la valeur indiquée plutôt que le pointeur lui-même.

La mémoire elle-même persiste, mais elle fuit car vous ne fournissez pas le pointeur alloué à l’appelant. En outre, vous imprimez a moment où vous devriez imprimer *a . Enfin, vous ne retournez pas un int de f1 .

Essayer:

 void f1(int **b) { *b = malloc(sizeof(int)); **b = 5; } int main() { int *a; f1(&a); printf("%d\n", *a); free(a); return 0; } 

Supposons que vous affectiez une valeur NULL à un avant d’appeler la fonction f1 . Maintenant, la manière dont f1 est défini prend son argument (pointeur sur un int ) par valeur. C’est-à-dire que b sera une autre variable de type int * qui sera une copie de a . Donc, b aura aussi une valeur de NULL . Maintenant, dans f1 vous modifiez la valeur par b en lui atsortingbuant l’adresse de la mémoire allouée dynamicment à l’aide de malloc . Disons que l’adresse mémoire est 0x123 . À la suite de cette affectation, b a changé sa valeur de NULL en 0x123 mais a (dans main ) continue à contenir NULL , car changer b ne changera pas a , car il s’agit de deux variables distinctes. Par conséquent, lorsque vous revenez de la fonction f1 a rest inchangé.

Il y a 2 façons de résoudre ce problème. Vous pouvez faire en sorte que la fonction f1 renvoie la valeur du b modifié, puis la réaffecter à une entrée main et à deux, vous pouvez transmettre l’adresse a par afin que toute modification effectuée dans la f1 affecte également une f1 main .

 // f1 now returns the value of b. int* f1() { int *b = malloc(sizeof(int)); *b = 5; return b; } int main() { int *a = NULL; a = f1(); // assign the return value of f1 to a. printf("%d\n", *a); // prints 5...not its *a not just a. return 0; } 

.

 // f1 now takes the address of a. void f1(int **b) { *b = malloc(sizeof(int)); // you are actually altering a indirectly. **b = 5; } int main() { int *a = NULL; f1(&a); // now pass the address of a to f1. printf("%d\n", *a); // prints 5...not its *a not just a. return 0; } 

L’adresse int *b est supprimée au retour de la fonction. Pour le sauvegarder, vous devez utiliser le pointeur d’un pointeur.

 int f1(int ** b) { *b = malloc(sizeof(int)); **b = 5; } 

En fait, votre problème n’est pas lié à malloc, mais bien au fait que vous transmettez la valeur actuelle du pointeur, plutôt que son adresse. Essayez ce qui suit:

 int f1(int ** b) { *b = malloc(sizeof(int)); **b = 5; } int main() { int * a; f1(&a); printf("%d\n", *a); return 0; } 

En passant la valeur du pointeur comme vous l’étiez, il n’y avait aucun moyen de stocker la valeur créée par malloc dans le pointeur.