23 votes

Pourquoi vouloir allouer de la mémoire sur le tas plutôt que sur la pile ?

Duplicata possible :
Quand est-il préférable d'utiliser un Stack au lieu d'un Heap et vice versa ?

J'ai lu quelques-unes des autres questions concernant le tas et la pile, mais elles semblent se concentrer davantage sur ce que font le tas et la pile que sur les raisons de les utiliser.

Il me semble que l'allocation à la pile serait presque toujours préférée car elle est plus rapide (il suffit de déplacer le pointeur de la pile plutôt que de chercher un espace libre dans le tas), et vous n'avez pas à libérer manuellement la mémoire allouée lorsque vous avez fini de l'utiliser. La seule raison que je vois pour utiliser l'allocation au tas est de créer un objet dans une fonction et de l'utiliser ensuite en dehors de la portée de cette fonction, puisque la mémoire allouée à la pile est automatiquement désallouée après le retour de la fonction.

Y a-t-il d'autres raisons d'utiliser l'allocation au tas au lieu de l'allocation à la pile dont je n'ai pas connaissance ?

39voto

caf Points 114951

Il y a plusieurs raisons :

  • La principale est qu'avec l'allocation au tas, vous disposez du contrôle le plus souple sur la durée de vie de l'objet (de l'allocation au tas à l'allocation au tas). malloc / calloc à free ) ;
  • L'espace de la pile est généralement une ressource plus limitée que l'espace du tas, du moins dans les configurations par défaut ;
  • L'échec de l'allocation d'espace de tas peut être géré de manière élégante, alors que le fait de manquer d'espace de pile est souvent irrécupérable.

Sans la souplesse de la durée de vie des objets, il serait pratiquement impossible d'écrire des structures de données utiles telles que les arbres binaires et les listes chaînées.

20voto

Kevin Montrose Points 11936
  1. Vous voulez qu'une allocation vive au-delà de l'invocation d'une fonction.
  2. Vous voulez conserver l'espace de la pile (qui est généralement limité à quelques Mo).
  3. Vous travaillez avec de la mémoire relocalisable (Win16, bases de données, etc.), ou vous voulez récupérer des échecs d'allocation.
  4. Tout ce qui est de longueur variable. Vous pouvez contourner ce problème, mais votre code sera vraiment désagréable.

Le plus important est le numéro 1. Dès que vous entrez dans une quelconque forme de concurrence ou d'IPC, le numéro 1 est partout. Même la plupart des applications non triviales à un seul fil sont difficiles à concevoir sans une certaine allocation de tas. Cela reviendrait pratiquement à simuler un langage fonctionnel en C/C++.

10voto

Chris Lutz Points 34157

Donc je veux faire une chaîne. Je peux le faire sur le tas ou sur la pile. Essayons les deux :

char *heap = malloc(14);
if(heap == NULL)
  {
    // bad things happened!
  }
strcat(heap, "Hello, world!");

Et pour la pile :

char stack[] = "Hello, world!";

Donc maintenant j'ai ces deux cordes à leurs places respectives. Plus tard, je veux les rendre plus longues :

char *tmp = realloc(heap, 20);
if(tmp == NULL)
  {
    // bad things happened!
  }
heap = tmp;
memmove(heap + 13, heap + 7);
memcpy(heap + 7, "cruel ", 6);

Et pour la pile :

// umm... What?

Ce n'est qu'un avantage, et d'autres ont mentionné d'autres avantages, mais celui-ci est plutôt agréable. Avec le tas, nous pouvons au moins essayer d'augmenter l'espace qui nous est alloué. Avec la pile, nous sommes coincés avec ce que nous avons. Si nous voulons de l'espace pour grandir, nous devons tout déclarer d'emblée, et nous savons tous à quel point cela pue de voir cela :

char username[MAX_BUF_SIZE];

4voto

squelart Points 5118

La raison la plus évidente d'utiliser le tas est lorsque vous appelez une fonction et que vous avez besoin de récupérer quelque chose de longueur inconnue. Parfois, l'appelant peut passer un bloc de mémoire et une taille à la fonction, mais dans d'autres cas, ce n'est pas pratique, surtout si le contenu retourné est complexe (par exemple, une collection d'objets différents avec des pointeurs qui volent partout, etc.)

3voto

Chuck Points 138930

Les limites de taille sont un obstacle majeur dans de nombreux cas. La pile est généralement mesurée en mégaoctets ou même en kilooctets (c'est le cas de tout sur la pile), alors que tous les PC modernes vous permettent quelques gigaoctets de tas. Donc, si vous devez utiliser une grande quantité de données, vous avez absolument besoin du tas.

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