467 votes

Pourquoi alloca n'est pas considéré comme une bonne pratique?

Alloca alloue de la mémoire à Stack plutôt qu'à heap, ce qui est le cas dans malloc. Donc, quand je reviens de la routine, la mémoire est libérée. Donc, en fait cela résout mon problème de libérer de la mémoire allouée dynamiquement. Libérer de la mémoire allouée par malloc est un casse-tête majeur et si quelque peu manqué conduit à toutes sortes de problèmes de mémoire.

Donc, ma question est que malgré les caractéristiques ci-dessus, l'utilisation d'alloca est déconseillée, pourquoi?

302voto

Sean Bright Points 39480

La réponse est là, dans l' man page (au moins sous Linux):

VALEUR DE RETOUR L'alloca() renvoie un pointeur vers le début de l' l'espace alloué. Si l' répartition des causes un débordement de pile, le comportement du programme n'est pas défini.

Ce qui ne veut pas dire qu'il ne doit jamais être utilisé. L'un des projets OSS je travaille sur l'utilise abondamment, et aussi longtemps que vous n'êtes pas en abuser (alloca'ing valeurs énormes), c'est la fin. Une fois que vous passez devant le "de quelques centaines d'octets", c'est le moment d'utiliser malloc et amis, à la place. Vous pouvez toujours obtenir les échecs d'allocation, mais au moins vous aurez une indication de l'échec au lieu de simplement souffler la pile.

243voto

Igor Zevaka Points 32586

L'un des plus mémorable des bugs que j'ai eu était de le faire avec une fonction inline qui utilisé alloca. Il se manifeste comme un débordement de la pile (car elle alloue sur la pile) à des points aléatoires de l'exécution du programme.

Dans le fichier d'en-tête:

void DoSomething() {
   wchar_t* pStr = alloca(100);
   //......
}

Dans la mise en œuvre de fichier:

void Process() {
   for (i = 0; i < 1000000; i++) {
     DoSomething();
   }
}

Donc ce qui s'est passé a été le compilateur inline DoSomething de la fonction et de toute la pile des allocations qui se passe à l'intérieur d' Process() la fonction et donc de soufflage de la pile. Dans ma défense (et je n'étais pas celui qui a trouvé le problème, j'ai dû aller et pleurer à l'un des principaux développeurs quand je ne pouvais pas le faire), il n'était pas hétéro alloca, il a été l'un des ATL chaîne de macros de conversion.

La conclusion est donc - ne pas utiliser alloca dans les fonctions que vous pensez peut-être inline.

102voto

tristopia Points 5074

Ancienne question mais personne n'a mentionné qu'elle devrait être remplacée par des tableaux de longueur variable.

 char arr[size];
 

au lieu de

 char *arr=alloca(size);
 

C'est dans le standard C99 et existait comme extension de compilateur dans de nombreux compilateurs.

71voto

Arthur Ulfeldt Points 45059

alloca() est très utile si vous ne pouvez pas utiliser une variable locale du fait de sa taille devra être déterminée au moment de l'exécution et vous pouvez garantir de manière absolue que le pointeur que vous obtenez à partir d'alloca() ne pourra être utilisé qu'après cette fonction renvoie.

Vous pouvez être relativement sûr, si vous

  • ne pas retourner le pointeur, ou quoi que ce soit qui le contient.
  • ne pas stocker le pointeur dans une structure alloué sur le tas
  • ne laissez pas n'importe quel autre thread utiliser le pointeur

Le vrai danger vient de la chance que quelqu'un d'autre, ne pas violer ces conditions un peu plus tard. Avec cela à l'esprit, il est idéal pour passer des tampons de fonctions de formatage de texte en eux :)

45voto

FreeMemory Points 4742

J’ai trouvé ce lien, qui a aussi une explication très utile d’utiliser alloca pourquoi peut être difficile et dangereux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X