Quelle est la manière correcte/préférée d'allouer de la mémoire dans une API C ?
Je vois, dans un premier temps, deux options :
1) Laisser l'appelant faire toute la gestion de la mémoire (externe) :
myStruct *s = malloc(sizeof(s));
myStruct_init(s);
myStruct_foo(s);
myStruct_destroy(s);
free(s);
El _init
y _destroy
sont nécessaires car de la mémoire supplémentaire peut être allouée à l'intérieur, et elle doit être gérée quelque part.
Cela a l'inconvénient d'être plus long, mais aussi le malloc peut être éliminé dans certains cas (par exemple, on peut lui passer un struct alloué par la pile :
int bar() {
myStruct s;
myStruct_init(&s);
myStruct_foo(&s);
myStruct_destroy(&s);
}
De plus, il est nécessaire que l'appelant connaisse la taille de la structure.
2) Cacher malloc
en _init
y free
en _destroy
.
Avantages : code plus court, puisque les fonctions seront appelées de toute façon. Structures complètement opaques.
Inconvénients : On ne peut pas passer une structure allouée d'une manière différente.
myStruct *s = myStruct_init();
myStruct_foo(s);
myStruct_destroy(foo);
Je penche actuellement pour le premier cas ; mais encore une fois, je ne connais pas la conception des API C.
2 votes
En fait, je pense que ce serait une excellente question d'entretien, pour comparer et contraster les deux modèles.
3 votes
Voici un article d'Armin Ronacher sur la façon de rendre les structures opaques tout en permettant de personnaliser l'allocation : lucumr.pocoo.org/2013/8/18/belles-bibliothèques-natives