polimeros nitinol metalicos memoria materiales inteligentes forma ejemplos con aleaciones alambre c++ language-lawyer heap-memory stdstring

c++ - nitinol - polimeros con memoria de forma



¿Está garantizado que std:: string no devuelva la memoria de forma espontánea? (4)

¿Está garantizado por el estándar que std::string no devolverá espontáneamente la memoria asignada si se reasigna desde una cadena de un tamaño más pequeño?

En otras palabras:

std::string str = "Some quite long string, which needs a lot of memory"; str = ""; str = "A new quite long but smaller string"; // Guaranteed to not result in a heap allocation?

Lo pregunto porque dependo de esto para evitar la fragmentación del montón.


¿Está garantizado por el estándar que std :: string no devolverá espontáneamente la memoria asignada si se reasigna desde una cadena de un tamaño más pequeño?

Independientemente de la respuesta real (que es "No, no hay garantía"), debe emplear el siguiente principio: Si no es obvio que tenga que ser así, entonces no asuma que así es.

En su caso específico, si desea un control estricto del comportamiento del montón, es posible que no quiera usar std::string s (tal vez; depende). Y es posible que no desee utilizar el asignador predeterminado (de nuevo, quizás); y es posible que desee memorizar cadenas ; Lo que debe hacer es hacer menos suposiciones, medir si es posible y tener un diseño explícito para garantizar que se cumplan sus necesidades.


No hay garantía alguna.

[string.cons]/36 define la asignación de un const char* a un std::string en el término de una asignación de movimiento, cuya definición es:

[string.cons]/32

basic_string& operator=(basic_string&& str) noexcept(/*...*/)

Efectos : Mover asigna como un contenedor de secuencia, excepto que los iteradores, punteros y referencias pueden ser invalidados.

Esto demuestra que el Comité dejó que la implementación eligiera libremente entre una operación de invalidación y una más conservadora. Y para hacer las cosas aún más claras:

[basic.string]/4

Las referencias, los punteros y los iteradores que se refieren a los elementos de una secuencia de basic_string pueden ser invalidados por los siguientes usos de ese objeto cadena de cadena básica:

  • (4.1) como un argumento para cualquier función de biblioteca estándar que toma una referencia a basic_string non-const como un argumento.
  • (4.2) Llamar a funciones no constantes, excepto el operator[] , at , data , front , back , begin , rbegin , end y rend .

Lo pregunto porque dependo de esto para evitar la fragmentación del montón.

std::string toma como parámetro de plantilla un asignador. Si está realmente preocupado por una posible fragmentación del montón, puede escribir el suyo propio, que con algunas heurísticas podría tener una estrategia de asignación adecuada para sus necesidades.

En la práctica, la mayoría de las implementaciones que conozco no reasignarán la memoria en el caso de su pregunta. Esto se puede verificar probando y / o revisando su documento de implementación y eventualmente el código fuente.


Si sus cadenas son cortas (hasta 15 o 22 bytes, dependiendo del compilador / lib. Est.) Y está usando un compilador relativamente reciente en C ++ 11 o posterior, es probable que se beneficie de la Optimización de cadenas cortas ( SSO). En este caso, el contenido de la cadena no se asigna por separado en el montón.

Este enlace también contiene muchos detalles sobre implementaciones comunes y estrategias de asignación.

Sin embargo, ambas cadenas en su ejemplo son demasiado largas para SSO.


La referencia de CPP indica que la asignación a un puntero a carácter

Reemplaza los contenidos con los de la cadena de caracteres terminados en nulo apuntados a s como si * este = cadena (s) básica (s), lo que implica una llamada a Traits :: length (s).

Este "como si" en realidad se reduce a una asignación de valor, por lo que el siguiente escenario es bastante posible:

  1. Se crea una nueva cadena temporal.
  2. Esta cadena roba su contenido a través de la asignación a una referencia de valor.