Dans quel but dois-je utiliser std::get_temporary_buffer
? Standard dit ce qui suit:
Obtient un pointeur vers le stockage suffisant pour stocker jusqu'à n objets T adjacents.
Je pensais que le tampon serait alloué sur la pile, mais ce n'est pas vrai. Selon la norme C ++, ce tampon n'est en fait pas temporaire. Quels avantages cette fonction a-t-elle sur la fonction globale ::operator new
, qui ne construit pas non plus les objets. Ai-je raison de dire que les affirmations suivantes sont équivalentes?
int* x;
x = std::get_temporary_buffer<int>( 10 ).first;
x = static_cast<int*>( ::operator new( 10*sizeof(int) ) );
Cette fonction n'existe-t-elle que pour le sucre syntaxique? Pourquoi y a-t-il temporary
dans son nom?
Un cas d'utilisation a été suggéré dans le Dr. Dobb's Journal du 1er juillet 1996 pour l'implémentation d'algorithmes:
Si aucun tampon ne peut être alloué, ou s'il est plus petit que demandé, l'algorithme fonctionne toujours correctement, il ralentit simplement.
std::get_temporary_buffer
sera obsolète en C ++ 17.Réponses:
Stroustrup dit dans "Le langage de programmation C ++" ( §19.4.4 , SE):
Il commence également l'introduction des deux fonctions avec:
... mais ne semble pas fournir de définition de temporaire ou à plus long terme .
Une anecdote dans "From Mathematics to Generic Programming" mentionne que Stepanov a fourni une implémentation fictive d'espace réservé dans la conception originale de la STL:
la source
operator new
avec des arguments successivement plus petits jusqu'à ce que l'allocation réussisse. Aucune optimisation spéciale là-bas.crazy_allocator
get_temporary_buffer
. Cependant, si nous recevons moins que le montant demandé (ce qui serait vraiment dommage), nous continuons d'essayer de faire notre travail avec le stockage que nous avons. Peut-être mieux que d'attraper lesbad_alloc
exceptions causées par la tentative d'allouer plus de mémoire que disponible. Cependant, l'utilité réelle se maintient et tombe avec une bonne mise en œuvre.Le gars de la bibliothèque standard de Microsoft dit ce qui suit ( ici ):
la source
La norme dit qu'elle alloue du stockage pour un maximum d'
n
éléments. En d'autres termes, votre exemple peut renvoyer une mémoire tampon suffisamment grande pour 5 objets seulement.Il semble cependant assez difficile d'imaginer un bon cas d'utilisation pour cela. Peut-être que si vous travaillez sur une plate-forme très limitée en mémoire, c'est un moyen pratique d'obtenir «autant de mémoire que possible».
Mais sur une plate-forme aussi contrainte, j'imagine que vous contourneriez le plus possible l'allocateur de mémoire et utiliseriez un pool de mémoire ou quelque chose sur lequel vous avez un contrôle total.
la source
La fonction est obsolète dans C ++ 17, donc la bonne réponse est maintenant "sans but, ne l'utilisez pas".
la source
ptrdiff_t request = 12 pair<int*,ptrdiff_t> p = get_temporary_buffer<int>(request); int* base = p.first; ptrdiff_t respond = p.sencond; assert( is_valid( base, base + respond ) );
la réponse peut être inférieure à la demande .
size_t require = 12; int* base = static_cast<int*>( ::operator new( require*sizeof(int) ) ); assert( is_valid( base, base + require ) );
la taille réelle de la base doit être supérieure ou égale à exiger .
la source
Peut-être (juste une supposition) que cela a quelque chose à voir avec la fragmentation de la mémoire. Si vous continuez à allouer et à désallouer beaucoup de mémoire temporelle, mais à chaque fois que vous le faites, vous allouez de la mémoire prévue à long terme après avoir alloué la température, mais avant de la désallouer, vous pouvez vous retrouver avec un tas fragmenté (je suppose).
Ainsi, le get_temporary_buffer pourrait être destiné à être un morceau de mémoire plus gros que ce dont vous auriez besoin qui est alloué une fois (peut-être qu'il y a de nombreux morceaux prêts à accepter plusieurs demandes), et chaque fois que vous avez besoin de mémoire, vous obtenez juste l'un des morceaux. Ainsi, la mémoire ne se fragmente pas.
la source