34 votos

¿Por qué no hay reasignación funcionalidad en C++ asignadores?

En C, el estándar de gestión de la memoria son funciones malloc(), realloc() y free(). Sin embargo, C++ stdlib asignadores sólo paralela de dos de ellos: no hay reasignación de la función. Por supuesto, no sería posible hacer exactamente el mismo como realloc(), porque simplemente la copia de la memoria no es adecuado para los no-tipos de áridos. Pero hay un problema, digamos, de esta función:

bool reallocate (pointer ptr, size_type num_now, size_type num_requested);

donde

  • ptr está previamente asignado con el mismo asignador de num_now objetos;
  • num_requested >= num_now;

y la semántica de la siguiente manera:

  • si el colocador puede ampliar dado bloque de memoria en ptr a partir del tamaño de num_now objetos a num_requested objetos, lo hace (dejando adicionales de memoria sin inicializar) y devuelve true;
  • otra cosa no hace nada y devuelve false.

Por supuesto, esto no es muy simple, pero asignadores, como yo lo entiendo, son en su mayoría destinado a los contenedores y contenedores de código es generalmente complicado ya.

Dada una función, std::vector, dicen, podría crecer como sigue (en pseudocódigo):

if (allocator.reallocate (buffer, capacity, new_capacity))
  capacity = new_capacity;     // That's all we need to do
else
  ...   // Do the standard reallocation by using a different buffer,
        // copying data and freeing the current one

Asignadores de que son incapaces de cambiar el tamaño de la memoria por completo sólo podría implementar una función incondicional return false;.

Hay tan pocos de reasignación de la capacidad de asignación de implementación que no iba a valer la pena molestarse? O hay algunos problemas que he pasado por alto?

19voto

5ound Puntos 907

De: http://www.sgi.com/tech/stl/alloc.html

Este es probablemente el más cuestionable decisión de diseño. Habría probablemente ha sido un poco más útil proporcionar una versión de reasignar que cambiado el tamaño de la objeto existente sin necesidad de copiar o devuelve NULL. Esto habría hecho que se directamente útil para los objetos de la copia los constructores. También habría evitar la copia innecesaria en los casos en el que el objeto original no había sido completamente llena.

Por desgracia, esto habría prohibido el uso de la realloc de la C biblioteca. Esto a su vez habría añadido la complejidad de muchos de asignación de las implementaciones, y habría hecho la interacción con la memoria de depuración las herramientas más difícil. Por lo tanto hemos decidido en contra de esta alternativa.

14voto

stinky472 Puntos 4864

Esto es en realidad un defecto de diseño que Alexandrescu señala con el estándar asignadores (no operador new[]/delete[] pero lo que originalmente eran la stl asignadores utilizados para implementar std::vector, por ejemplo).

Un realloc puede ocurrir mucho más rápido que un malloc, memcpy, y gratis. Sin embargo, mientras que el bloque de memoria se pueden cambiar de tamaño, también puede mover de la memoria a una nueva ubicación. En el último caso, si el bloque de memoria que consiste en la no-PODs, todos los objetos se necesitan para ser destruidos y copia-construido después de la realloc.

Lo principal de la biblioteca estándar de necesidades para dar cabida a esto como una posibilidad , es una de reasignar la función como parte del estándar de asignación de la interfaz pública. Una clase std::vector podría utilizar incluso si el valor predeterminado de la aplicación es malloc el recién tamaño de bloque y libre de la antigua. Tendría que ser una función que es capaz de destruir y copia de la construcción de los objetos en la memoria, aunque, no se puede tratar de la memoria en una opaca de la moda si lo hizo esta. Hay un poco de complejidad y se requieren poco más de la plantilla de trabajo que puede ser por eso que se ha omitido de la biblioteca estándar.

std::vector<...>::la reserva no es suficiente: se ocupa de un caso donde el tamaño de la maceta puede ser anticipado. Para realmente de tamaño variable listas, un realloc solución podría hacer contiguos de contenedores como std::vector mucho más rápido, especialmente si se puede tratar con realloc casos donde el bloque de memoria correctamente el tamaño sin ser movido, en cuyo caso se puede omitir la llamada copia de los constructores y los destructores de los objetos en la memoria.

8voto

Mark Ransom Puntos 132545

Lo que estamos pidiendo es lo que esencialmente vector::reserve . Sin mover la semántica de los objetos, no hay manera de reasignar la memoria y mover los objetos a su alrededor sin hacer una copia y destruir.

2voto

tlayton Puntos 1171

Debido a la orientada a objetos en la naturaleza de C++, y la inclusión de los diversos estándar de los tipos de envases, creo que es simplemente que menos atención se centró en la dirección de administración de memoria que en C. estoy de acuerdo en que hay casos en que un realloc() sería útil, pero la presión para remediar esta es mínima, como casi todos los de la funcionalidad resultante puede ser adquirida mediante el uso de contenedores en su lugar.

2voto

Pavel Radzivilovsky Puntos 11613

Supongo que esta es una de las cosas donde dios salió mal, pero yo era demasiado perezoso para escribir en el comité de normas.

No debería haber sido un realloc para la matriz de asignaciones:

p = renew(p) [128];

o algo como eso.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X