c++ - mpi_any_source - mpi_recv
¿Puede std:: vector hacer uso de la optimización del pequeño buffer? (2)
23.2.1 / p10 / b6:
A menos que se especifique lo contrario ...
- ninguna función swap () invalida cualquier referencia, puntero o iterador que haga referencia a los elementos de los contenedores que se intercambian. ...
En ninguna parte "especifica lo contrario" para el vector
. Así que esto proscribe al SBO por vector
.
string
no está obligado por esta regla porque "especifica lo contrario" en 21.4.1 / p6:
Las referencias, punteros e iteradores que hacen referencia a los elementos de una secuencia basic_string pueden invalidarse mediante los siguientes usos de ese objeto basic_string:
- como argumento para cualquier función de biblioteca estándar tomando como referencia una cadena básica no const. como un argumento. ^ 234
234) Por ejemplo, como un argumento para las funciones no miembro swap () (21.4.8.8), operator >> () (21.4.8.9) y getline () (21.4.8.9), o como un argumento para basic_string: :intercambiar()
Me preguntaba con mi colega hoy si std :: vector puede implementarse para hacer uso de la optimización de búfer pequeño. Al observar el borrador de C ++ 11, leo en 23.3.1p8
La expresión a.swap (b), para los contenedores ayb de un tipo de contenedor estándar distinto de una matriz, intercambiará los valores de ayb sin invocar ninguna operación de movimiento, copia o intercambio en los elementos de contenedor individuales.
Eso al principio parece prohibir la optimización de pequeños búferes, pero bajo la regla de si-si, se nos permitiría realizar una optimización de búfer pequeña para tipos que no son de clase (ya que no podemos observar que se realice la copia). El siguiente texto parece ser más difícil de "engañar"
Cada iterador que hace referencia a un elemento en un contenedor antes del intercambio debe hacer referencia al mismo elemento en el otro contenedor después del intercambio.
¿Es esto suficiente para evitar la implementación de la optimización del pequeño buffer para std :: vector? ¿Hay algún otro obstáculo o es posible tener un std :: vector con SBO?
Además del problema con la invalidación del iterador, existe un argumento de seguridad para evitar la optimización del pequeño buffer.
Si escribe overrun a std::vector
, obtienes corrupción de montón, lo cual es bastante difícil de predecir qué se sobreescribe y muy difícil de aprovechar para la ejecución de código arbitrario.
Si el búfer está en cambio incrustado en una variable local, un desbordamiento destruye la pila y el atacante probablemente obtendrá control sobre la dirección de retorno, que es mucho más útil (ataques de devolución de libc, por ejemplo).