48 votes

Std :: vector peut-il utiliser l'optimisation de petits tampons?

Je me demandais avec mon collègue aujourd'hui que std::vector peut être mis en œuvre pour rendre l'utilisation de la mémoire tampon de petite optimisation. En regardant dans le C++11 projet, j'ai lu au 23.3.1p8

L'expression d'un.swap(b), pour les récipients a et b d'un conteneur standard de type autre que la matrice de, échange les valeurs de a et b sans avoir à tout déplacer, copier, ou des opérations de swap sur le conteneur éléments.

Qui au premier abord semble à proscrire petit tampon de l'optimisation, mais dans le cas de la règle, nous serions autorisés à faire encore petit tampon de l'optimisation pour les non-types de classe (puisque nous ne pouvons pas observer la copie en cours). Le texte suivant apparaît plus difficile à "tromper"

Chaque itérateur se référant à un élément dans un conteneur avant le swap doit se référer à la même élément dans l'autre récipient après l'échange.

Est-ce suffisant pour empêcher la mise en œuvre de la mémoire tampon de petite optimisation pour les std::vector? Existe-il d'autres barrages ou est-il éventuellement possible d'avoir un std::vector avec SBO?

47voto

Howard Hinnant Points 59526

23.2.1 / p10 / b6:

À moins d'indication contraire ...

  • pas de swap() la fonction remplace toutes les références, les pointeurs, ou les itérateurs en se référant aux éléments des conteneurs d'être échangé. ...

Nulle part il n'est "spécifier autrement" pour vector. Donc, ce hors-la-loi le SBO pour vector.

string n'est pas lié par cette règle, car il n' "spécifier autrement" dans 21.4.1/p6:

Les références, les pointeurs et les itérateurs en se référant aux éléments d'un basic_string séquence peut être invalidé par les utilisations suivantes de l' basic_string objet:

  • comme un argument de toute la bibliothèque standard fonction prenant une référence à la non-const basic_string comme un argument.^234

234) Par exemple, comme un argument de non-fonctions de membre de swap() (21.4.8.8), l'opérateur>>() (21.4.8.9), et getline() (21.4.8.9), ou comme un argument de basic_string::swap()

1voto

Ben Voigt Points 151460

Outre le problème avec itérateur à l'annulation, il y a un argument de la sécurité pour éviter le petit tampon de l'optimisation.

Si l'écrit envahi un std::vector, vous obtenez tas de corruption, ce qui est assez difficile de prédire ce que sera écrasé et très difficile à effet de levier pour l'exécution de code arbitraire.

Si la mémoire tampon est plutôt intégré dans une variable locale, un dépassement des ordures de la pile, et l'attaquant va probablement reprendre le contrôle de l'adresse de retour, ce qui est beaucoup plus utile (retour-à-la libc attaques, par exemple).

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