2009-04-15 14 views
5

En C++, creo que una forma mejor de tratar con la reasignación es usar un vector STL, ya que garantiza las ubicaciones de almacenamiento contiguas.¿El vector STL es una mejor versión de realloc?

que tienen pregunta pareja para entender la diferencia:

  1. ¿Hay alguna situación en la que tengo que prefieren realloc sobre vectores?
  2. ¿Hay algo más (aparte del vector) que sea equivalente a realloc en C++?

Gracias,

Respuesta

14

Es solamente vector, que se garantiza que tiene memoria contigua. No los otros

realloc es una función de gestión de memoria C. Su uso no se fomenta en el código C++. Aquí está BS que le dice qué: Why doesn't C++ have an equivalent to realloc()?

Sin embargo, realloc() sólo se garantiza que funcione en matrices asignados por malloc() (y funciones similares) que contienen objetos sin constructores de copia definidos por el usuario. Además, recuerde que, contrariamente a las expectativas ingenuas, realloc() ocasionalmente copia su matriz de argumentos.

+1

realloc no funcionará con nada más que tipos de POD, ya que no conoce constructores/destructores. El vector – lothar

+0

también tiene la ventaja sobre la memoria de malloc en que se eliminarán cuando salgan del alcance, disminuyendo así las pérdidas de memoria cuando se lanzan excepciones, cuando se olvida de liberar() la memoria, etc. –

+0

@dirkgently Enlace roto, puede usted actualiza por favor? –

8

memoria contigua también está garantizada por realloc así que no es una razón para no usarlo.

Sin embargo, preferiría usar un vector en C++ ya que tiene un mayor nivel de abstracción, por lo tanto, hace que el código sea más fácil de escribir.

La única razón posible que puedo pensar para usar el realloc (sobre el vector) para un escenario tipo matriz, es la velocidad bruta. Es puede sea más rápido. Y hago hincapié en la palabra "puede" - medida, ¡no adivine!

Sin embargo, usted tiene que manejar sus propias reasignaciones, que es más trabajo. Prefiero tener un código que sea un poco más lento (suponiendo que siga funcionando lo suficientemente rápido, por supuesto), si puedo entregarlo y recibir un pago más rápido.

1

Supongo que es solo un vector.

No he visto a nadie que sugiera usar realloc en C++.

10

El conjunto de funciones C (malloc, calloc, realloc, free) son operaciones de memoria sin formato. Crearán/modificarán/liberarán un búfer en la memoria, pero la memoria no tendrá ningún tipo y no se invocarán constructores.

C++ no tiene un equivalente de realloc, pero sólo typesafe equivalentes a malloc/libre a través del uso de nuevo/nueva [] y de borrado/delete []. Las versiones C++ adquirirán la memoria del sistema y la inicializarán llamando a los constructores apropiados. Usando delete llamará a los destructores de los objetos y luego liberará la memoria.Las versiones C y C++ no son compatibles, si adquiere memoria con malloc (incluso si llama al constructor in situ en la memoria recibida) no puede liberarlo con delete/delete [] ya que es un comportamiento indefinido.

El uso de realloc en C++ puede ser inseguro, ya que copiará bit a bit los objetos de un área de memoria a la siguiente. Algunas veces sus objetos no se ocuparán adecuadamente de los movimientos de la memoria (digamos que su objeto tiene un atributo y una referencia a él, luego de moverlo en forma de bit la referencia apuntará a la posición anterior en lugar del atributo real). Dentro de vector, cuando la memoria necesita crecer, se adquiere una nueva memoria con new [] y luego todos los objetos son copiados (o copiados) en las nuevas posiciones usando las operaciones apropiadas de C++ antes de eliminar los elementos antiguos.

Siempre vector crece en tamaño (tamaño reservado, no se utiliza el tamaño) se creará una nueva área de memoria completa y movimiento todos los objetos. Por otro lado, realloc solo moverá el bloque de memoria a otra posición si no hay suficiente espacio contiguo después de que el puntero solo crezca. Vectores no disminuya el tamaño. Nunca. Cuando borra los elementos, la memoria reservada aún se mantiene.

Finalmente, hay un mayor nivel de abstracción en vector que en realloc incluso para los tipos de POD (que se pueden mover con construcciones C-safe). El equivalente a vector sería una estructura que contiene el puntero al búfer de memoria, un recuento de elementos usados ​​y reservados (tamaño de búfer) y el conjunto de funciones que tratan de adquirir más memoria según sea necesario y actualizar los índices con cada operación .

+1

Los vectores no disminuyen el tamaño, excepto cuando se llama a v.shrink_to_fit(), que es nuevo en C++ 11. Tenga en cuenta que una implementación puede elegir ignorar la llamada. – MaHuJa

+0

@MaHuJa: 'std :: vector (myVector) .swap (myVector);' en todas las implementaciones que conozco (no obligatorio) encoge el vector al tamaño apropiado. –

5

Uno de los principales beneficios de std :: vector es que cuando se reasigna internamente de crecimiento natural, elige un tamaño que es 2 veces mayor que el tamaño actual (por lo general, pero siempre es un multiplicador constante). Esto significa que push_back ha amortizado O (1) costo.

Realloc le dará un control más preciso sobre la forma de asignar memoria, pero con gran poder viene una gran responsabilidad. Si todo lo que está haciendo es el equivalente de push_back, y reasigna cada vez que agrega un elemento, es potencialmente una operación O (N) en cada adición a la matriz.

Cuestiones relacionadas