2009-03-15 5 views
3

J'ai un objet (A) qui a une liste composée d'objets (B). Les objets de la liste (B) sont des pointeurs, mais la liste elle-même doit-elle être un pointeur? Je migre de Java vers C++ et je ne suis toujours pas habitué à la pile/tas. La liste ne sera pas passée en dehors de la classe A, seulement les éléments de la liste. Est-ce une bonne pratique d'allouer la liste elle-même sur le tas juste au cas où?Une liste d'objets doit-elle être stockée sur le tas ou la pile?

De même, la classe qui contient la liste (A) devrait-elle aussi être sur le tas lui-même? Comme la liste, il ne sera pas transmis.

Répondre

6

Gardez à l'esprit que

  1. La liste ne serait sur la pile si l'objet-A était également sur la pile
  2. Même si la liste elle-même est pas sur le tas, il peut affecter son stockage du tas. C'est ainsi que fonctionnent les listes std :: list, std :: vector et la plupart des listes C++ - la raison en est que les éléments basés sur une pile ne peuvent pas croître.
  3. Ces jours-ci, la plupart des piles font environ 1mb, vous aurez donc besoin d'une assez grande liste d'objets assez gros avant de devoir vous en soucier. Même si votre pile n'était qu'environ 32ko, vous pourriez stocker près de huit mille pointeurs avant que cela ne pose problème.

OMI nouvelles personnes à la gestion de la mémoire explicite en C/C++ peuvent avoir tendance à overthink ces choses.

Sauf si vous écrivez quelque chose que vous savez aura des milliers d'objets de taille, il suffit de mettre la liste sur la pile. Sauf si vous utilisez des tableaux géants de style C dans une fonction, il y a de fortes chances que la mémoire utilisée par la liste se retrouve dans le tas de toute façon en raison des # 1 et # 2 ci-dessus.

-1

La pile est toujours la plus simple. Malheureusement, il a un gros inconvénient - vous devez connaître le nombre d'éléments à l'avance.

1

Il vaut mieux stocker une liste, si elle peut grandir, sur le tas. Puisque vous ne savez jamais ce que sera la pile d'exécution, le débordement est un réel danger, et les conséquences sont fatales.

Si vous connaissez absolument la limite supérieure de la liste, et qu'elle est petite par rapport à la taille de votre pile, vous pouvez probablement vous en sortir en allouant la liste.

+1

Si la liste stocke des pointeurs vers le tas, ne prendrait-il pas un grand nombre d'éléments pour provoquer un débordement de pile? Pour cette application, il serait assez fou pour la liste d'avoir plus de 30 éléments. – Alexander

+0

Si c'est la liste comme dans "std :: list" alors il ne stocke rien sur le tas. Bor est un autre conteneur STL. –

+1

TYPO: Je voulais dire "pile". STL ne stocke pas de choses sur la pile .... –

0

Je travaille dans des environnements où la pile peut être petite et la fragmentation des tas doit être évité, donc j'utiliser ces règles:

  • Si la liste est faible et une taille fixe connue, pile.

  • Si la liste est petite et une taille fixe inconnue, vous pouvez considérer à la fois le tas et alloca(). Utiliser le tas serait un bon choix si vous pouvez garantir que votre fonction n'alloue rien sur le tas pendant la durée de votre allocation. Si vous ne pouvez pas le garantir, vous demandez un fragment et alloca() serait un meilleur choix.

  • Si la liste est grande ou aura besoin de croître, utilisez le tas. Si vous ne pouvez pas garantir qu'il ne se fragmentera pas, nous avons tendance à avoir des recours pour cela dans notre gestionnaire de mémoire, tels que des allocations descendantes et des tas séparés.

La plupart des situations ne demandent pas aux gens de s'inquiéter de la fragmentation, dans ce cas, ils ne recommanderaient probablement pas l'utilisation de alloca.

En ce qui concerne la classe contenant la liste, si elle est locale à la portée de la fonction, je la mettrais sur la pile à condition que les structures de données internes ne soient pas extrêmement grandes.

0

Qu'entendez-vous par "liste". Si c'est std :: list (ou std :: vector ou tout autre conteneur STL) alors ça ne va rien stocker sur la pile alors ne vous inquiétez pas.

En cas de doute, regardez sizeof (A) et cela vous indique la quantité de mémoire qu'il utilisera lorsqu'il sera sur la pile.

Mais ... la décision devrait principalement être basée sur la durée de vie de l'objet. Les objets basés sur une pile sont détruits dès qu'ils sortent de la portée.

Questions connexes