33 votes

std :: string sans allocation de mémoire en magasin libre

J'ai une question très similaire à

Comment dois-je allouer un std::string sur la pile à l'aide de la glibc dans la chaîne de mise en œuvre?

mais je pense qu'il vaut la peine de demander à nouveau.

Je veux un std::string avec le stockage local qui déborde dans le magasin gratuit. std::basic_string donne un allocateur comme un paramètre du modèle, donc il semble que la seule chose à faire est d'écrire un programme d'allocation de locaux de stockage et de l'utiliser pour paramétrer l' basic_string, comme suit:

std::basic_string<
char, 
std::char_traits<char>, 
inline_allocator<char, 10> 
> 
x("test");

J'ai essayé d'écrire l' inline_allocator classe qui fonctionne de la manière que vous attendez: il se réserve de 10 octets pour le stockage, et si l' basic_string a besoin de plus de 10 octets, puis il appelle ::operator new(). Je ne pouvais pas le faire fonctionner. Dans le cadre de l'exécution de la ligne au-dessus de code, mon GCC 4.5 standard de la bibliothèque string appelle le constructeur de copie pour inline_allocator 4 fois. Il n'est pas clair pour moi qu'il y a un moyen judicieux d'écrire le constructeur de copie pour inline_allocator.

Dans les autres StackOverflow fil, Eric Melski fourni ce lien à une classe dans Chrome:

http://src.chromium.org/svn/trunk/src/base/stack_container.h

ce qui est intéressant, mais ce n'est pas une baisse-dans le remplacement pour std::string, car elle enveloppe l' std::basic_string dans un récipient de sorte que vous devez appeler une surchargé operator->() pour se retrouver à la std::basic_string.

Je ne peux pas trouver d'autres solutions à ce problème. Se pourrait-il qu'il n'y a pas de bonne solution? Et si cela est vrai, alors l' std::basic_string et std::allocator concepts très imparfait? Je veux dire, il semble que ce devrait être un très de base et les cas d'utilisation simple pour std::basic_string et std::allocator. Je suppose que l' std::allocator concept est principalement conçu pour les piscines, mais je pense qu'il devrait couvrir ce ainsi.

Il semble que la rvalue-référence sémantique de déplacement dans C++0x pourrait rendre possible l'écriture d' inline_allocator, si la chaîne de la bibliothèque est re-écrite, de sorte que basic_string utilise le constructeur de déplacement de son allocation au lieu de le constructeur de copie. Personne ne sait ce que la perspective est pour ce résultat?

Mon application a besoin de construire un million de petites chaînes ASCII par seconde, donc j'ai fini par écrire ma propre chaîne de longueur fixe de classe basée sur Boost.Array, ce qui fonctionne très bien, mais c'est encore de me tracasser.

16voto

templatetypedef Points 129554

Andrei Alexandrescu, programmeur C++ extraordinaire qui a écrit "Modern C++ Design" a écrit un excellent article sur la construction différents de la chaîne implémentations avec des systèmes de stockage. Son article (lien ici) décrit comment vous pouvez faire ce que vous avez décrite ci-dessus comme un cas particulier d'une manière beaucoup plus générale d'un système qui peut traiter toutes sortes de intelligent de l'allocation de mémoire requise. Ce n'est pas parlons std::string et se concentre plus sur un entièrement personnalisé en classe de chaînes de caractères, mais vous pouvez regarder dans comme il y a de vrais trésors dans la mise en œuvre.

10voto

Matthieu M. Points 101624

C++2011 va vraiment vous aider ici :)

Le fait est que l' allocator concept en C++03 a été paralysé. Une des conditions était qu'un allocateur de type A devrait être en mesure de libérer la mémoire de tout autre allocateur de type A... Malheureusement, cette exigence est également en contradiction avec la dynamique d'allocateurs de chaque accroché à sa propre piscine.

Howard Hinnant (qui gère la STL sous-groupe de C++ a été retenu et est la mise en œuvre d'un nouveau STL à partir de zéro pour C++0x) a exploré de pile, allocateurs sur son site web, que vous pouvez vous en inspirer.

6voto

Jerry Coffin Points 237758

Ce n'est généralement pas nécessaire. On l'appelle le "court optimisation de la chaîne", et la plupart des implémentations de std::string déjà inclus. Il peut être difficile à trouver, mais c'est généralement de là de toute façon.

Juste pour exemple, voici le concerné sso_string_base.h qui fait partie de MinGW:

  enum { _S_local_capacity = 15 };

  union
  {
_CharT           _M_local_data[_S_local_capacity + 1];
size_type        _M_allocated_capacity;
  };

L' _M_local_data membre est l'un, de l'espace pour stocker (jusqu'à) 15 caractères (plus un NUL de terminaison) sans affectation d'un espace sur le tas.

Si ma mémoire est bonne, le Dinkumware bibliothèque fournie avec VC++ alloue de l'espace pour 20 caractères, même s'il a été un moment depuis que j'ai regardé, donc je ne peux pas le jurer qu' (et la traque de beaucoup de n'importe quoi dans leurs en-têtes tend à être une douleur, donc je préfère éviter de regarder si je peux).

En tout cas, je donnerais de bonnes chances que vous avez été engagé dans que trop populaire passe-temps connu comme l'optimisation prématurée.

2voto

Zan Lynx Points 23100

Je crois que le code de Chrome juste encapsule les choses dans une belle coquille. Mais vous pouvez obtenir le même effet sans utiliser le Chrome wrapper conteneur.

Parce que l'allocation de l'objet est copié si souvent, il doit contenir une référence ou un pointeur vers la mémoire. Donc, ce que vous devez faire c'est de créer de la mémoire de stockage, de créer de l'allocateur de l'objet, puis d'appeler le std::string constructeur avec l'allocateur.

Il sera beaucoup wordier que l'utilisation de la classe wrapper, mais devrait obtenir le même effet.

Vous pouvez en voir un exemple détaillé de la méthode (toujours en utilisant le chrome des trucs à ma question sur la pile de vecteurs.

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