Les gens ont déjà fait remarquer que vous n'avez probablement pas besoin de vous soucier de libérer de la mémoire si vous quittez (ou annulez) votre code en cas d'erreur. Mais juste au cas où, voici un modèle que j'ai développé et que j'utilise beaucoup pour créer et détruire des ressources en cas d'erreur.NOTE: Je montre un motif ici pour faire un point, ne pas écrire de vrai code!
int foo_create(foo_t *foo_out) {
int res;
foo_t foo;
bar_t bar;
baz_t baz;
res = bar_create(&bar);
if (res != 0)
goto fail_bar;
res = baz_create(&baz);
if (res != 0)
goto fail_baz;
foo = malloc(sizeof(foo_s));
if (foo == NULL)
goto fail_alloc;
foo->bar = bar;
foo->baz = baz;
etc. etc. you get the idea
*foo_out = foo;
return 0; /* meaning OK */
/* tear down stuff */
fail_alloc:
baz_destroy(baz);
fail_baz:
bar_destroy(bar);
fail_bar:
return res; /* propagate error code */
}
Je peux parier que je vais obtenir des commentaires disant "c'est mauvais parce que vous utilisez goto". Mais c'est une utilisation disciplinée et structurée de goto qui rend le code plus clair, plus simple et plus facile à maintenir s'il est appliqué de manière cohérente. Vous ne pouvez pas obtenir un chemin de démontage simple et documenté à travers le code sans cela.
Si vous voulez voir ceci dans le vrai code commercial en service, jetez un oeil, par exemple, arena.c from the MPS (qui est par hasard un système de gestion de mémoire).
C'est une sorte d'essai d'un homme pauvre ... gestionnaire d'arrivée, et vous donne quelque chose qui ressemble un peu à un destructeur. Je vais maintenant avoir l'air d'un barbare, mais dans mes nombreuses années de travail sur le code C d'autres personnes, l'absence de chemins d'erreur clairs est souvent un problème très sérieux, en particulier dans le code réseau et d'autres situations peu fiables. Les présenter m'a occasionnellement fait un peu de revenus de consultance.
Il y a beaucoup d'autres choses à dire à propos de votre question - je vais juste laisser ce motif dans le cas où c'est utile.
Vous pouvez même utiliser la fonction atexit() et écrire une fonction pour libérer toute la mémoire allouée sur la liste chaînée (qui devrait être une variable globale dans ce cas) sur un simple appel à exit() - comme vous le feriez Il ne faut pas oublier de ne pas utiliser la sortie normale(). –
Mais pourquoi? Le système d'exploitation maintient déjà une liste de mémoire allouée. La duplication de cette fonctionnalité va simplement ralentir le processus d'arrêt sans autre bénéfice qu'un peu d'inflation de l'ego. Sauf si vous envisagez de porter votre application sur MSDOS, laissez l'os faire son travail. – Eclipse
Le pourquoi est parce que finalement la discipline et la fonctionnalité vous aideront à traquer les fuites de mémoire. Si vous le codez correctement, il peut être désactivé via une définition DEFINE ou MACRO. – ojblass