36 votes

Pourquoi n'y a-t-il pas de fonctionnalité de réallocation dans les allocateurs C ++?

C dans la norme de gestion de la mémoire fonctions sont malloc(), realloc() et free(). Cependant, C++ stdlib allocateurs parallèle, deux d'entre eux: il n'y a pas de réallocation de la fonction. Bien sûr, il ne serait pas possible de faire exactement la même chose que realloc(), parce que tout simplement la copie de la mémoire n'est pas approprié pour les non-types de regroupement. Mais y aurait-il un problème avec cette fonction:

bool reallocate (pointer ptr, size_type num_now, size_type num_requested);

  • ptr est allouée au préalable avec le même allocateur pour num_now objets;
  • num_requested >= num_now;

et de la sémantique comme suit:

  • si l'allocateur pouvez étendre la mémoire bloc ptr à partir de la taille pour num_now objets d' num_requested objets, il le fait (en laissant davantage de mémoire non initialisée) et les retours true;
  • sinon il ne fait rien et renvoie false.

Accordé, ce n'est pas très simple, mais allocateurs, ce que je comprends, sont là pour les conteneurs et les emballages " le code est généralement compliqué déjà.

Compte tenu de cette fonction, std::vector, par exemple, pourrait croître comme suit (pseudo-code):

if (allocator.reallocate (buffer, capacity, new_capacity))
  capacity = new_capacity;     // That's all we need to do
else
  ...   // Do the standard reallocation by using a different buffer,
        // copying data and freeing the current one

Allocateurs qui sont incapables de changer la taille de la mémoire au total pourrait tout mettre en œuvre une telle fonction par inconditionnelle return false;.

Il y a si peu de réaffectation capable de l'allocateur de mise en œuvre que ce ne serait pas la peine de s'embêter? Ou il y a quelques problèmes que j'ai négligé?

19voto

5ound Points 907

De: http://www.sgi.com/tech/stl/alloc.html

C'est probablement le plus discutable décision de conception. Il aurait probablement été un peu plus utile fournir une version de réaffecter que soit changé la taille de la objet existant sans les copier ou les retourné NULL. Ce qui aurait fait directement utile pour les objets à copier les constructeurs. Il aurait également éviter copie inutile dans les cas dans lequel l'objet d'origine n'avait pas été complètement rempli.

Malheureusement, cela aurait utilisation interdite de realloc de la C de la bibliothèque. Ce à son tour, aurait ajouté la complexité de nombreux allocateur implémentations, et aurait fait l'interaction avec la mémoire de débogage des outils de plus en plus difficile. Ainsi, nous avons décidé contre cette alternative.

15voto

stinky472 Points 4864

C'est en fait un défaut de conception qui Alexandrescu points avec la norme allocateurs (pas de nouvel opérateur[]/delete[] mais ce qui ont été à l'origine de la stl allocateurs utilisés pour mettre en œuvre std::vector, par exemple).

Un realloc peut se produire beaucoup plus rapide qu'un malloc, memcpy, et gratuit. Cependant, alors que le bloc de mémoire peut être redimensionnée, il peut aussi se déplacer de la mémoire vers un nouvel emplacement. Dans ce dernier cas, si le bloc de mémoire est constitué de non-PODs, tous les objets doivent être détruits, et la copie construit après le realloc.

La chose principale de la bibliothèque standard doit tenir compte de cette comme une possibilité est de réaffecter une partie de l'allocateur standard de l'interface publique. Une classe du type std::vector pourrait certainement utiliser même si l'implémentation par défaut est de malloc la nouvelle taille de bloc et gratuit à l'ancien. Il faudrait une fonction qui est capable de les détruire et de les copier-construire les objets de souvenir, il ne peut pas traiter de la mémoire dans une opaque de mode si elle l'a fait. Il y a un peu de complexité et il aurait besoin d'un peu plus de modèle de travail qui peut être pourquoi il a été omis de la bibliothèque standard.

std::vector<...>::la réserve n'est pas suffisante: elle s'attaque à un autre cas où la taille du conteneur peut être prévu. Pour vraiment de taille variable listes, un realloc solution pourrait faire contiguë conteneurs comme std::vector beaucoup plus vite, surtout si elle peut traiter avec realloc cas où le bloc de mémoire est correctement redimensionnée sans être déplacé, auquel cas il peut omettre l'appel de copier les constructeurs et les destructeurs des objets en mémoire.

8voto

Mark Ransom Points 132545

Ce que vous demandez, c'est essentiellement ce que vector::reserve fait. Sans déplacer la sémantique des objets, il n'y a aucun moyen de réallouer la mémoire et de déplacer les objets sans faire de copie ni de destruction.

2voto

tlayton Points 1171

En raison de la nature orientée objet de C ++ et de l'inclusion des différents types de conteneurs standard, je pense que c'est simplement que moins d'attention a été accordée à la gestion de la mémoire de direction qu'en C.Je conviens qu'il y a des cas où un realloc () serait utile , mais la pression pour y remédier est minime, car presque toutes les fonctionnalités résultantes peuvent être obtenues en utilisant des conteneurs à la place.

2voto

Pavel Radzivilovsky Points 11613

Je suppose que c'est l'une des choses où Dieu a mal tourné, mais j'étais trop paresseux pour écrire au comité des normes.

Il aurait dû y avoir une réaffectation des allocations de tableau:

p = renew(p) [128];

ou quelque chose comme ça.

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