2010-08-14 17 views
54

¿Cómo puedo realloc en C++? Parece que falta en el idioma - ¡hay new y delete pero no resize!¿Cómo se 'realloc' en C++?

Lo necesito porque como mi programa lee más datos, necesito reasignar el búfer para mantenerlo. No creo que delete en el puntero antiguo y new en uno nuevo, más grande, es la opción correcta.

+7

Stroustrup respondió esto hace mucho tiempo, mira: http://www2.research.att.com/~bs/bs_faq2.html#renew (Es un buen comienzo si eres nuevo en C++ junto con las preguntas frecuentes de C++ de Cline.) – dirkgently

+4

La respuesta a la que hace referencia @dirkgently ahora está en: http://www.stroustrup.com/bs_faq2.html#renew - y las preguntas frecuentes de Cline ahora son parte de las preguntas más frecuentes: https://isocpp.org/faq – maxschlepzig

Respuesta

35

Uso :: std :: vector!

Type* t = (Type*)malloc(sizeof(Type)*n) 
memset(t, 0, sizeof(Type)*m) 

convierte

::std::vector<Type> t(n, 0); 

Entonces

t = (Type*)realloc(t, sizeof(Type) * n2); 

convierte

t.resize(n2); 

Si desea pasar el puntero en la función, en lugar de

Foo(t) 

uso

Foo(&t[0]) 

Es correcto código C++ absolutamente, porque el vector es un C-smart array.

+1

¿No debería la línea memset ser memset (t, 0, sizeof (T) * n) ;? n en lugar de m? – anthom

+1

@anthom sí. realmente debería ser 'Type * t = static_cast (malloc (n * sizeof * t));' –

+0

Con C++ 11 ahora se usaría 't.data()' en lugar de '& t [0]' – knedlsepp

39

La opción correcta es probablemente utilizar un contenedor que haga el trabajo por usted, como std::vector.

new y delete no se puede cambiar el tamaño, porque se asignan suficiente memoria para contener un objeto del tipo dado. El tamaño de un tipo dado nunca cambiará. Hay new[] y delete[] pero casi nunca hay una razón para usarlos.

Lo que ocurre en C realloc es probable que sea sólo un malloc, memcpy y free, de todos modos, aunque se permiten los administradores de memoria que hacer algo inteligente si hay suficiente memoria libre contiguo disponible.

+0

So ¿Cuál sería la forma correcta de implementar un creciente buffer en C++? Actualmente tengo 'char * buf = (char *) malloc (size)', cuando se vuelve demasiado pequeño hago 'buf = realloc (size + more_size); size + = more_size'. ¿Cómo puedo hacerlo con el vector? – bodacydo

+6

@bodacydo: no implementan la memoria intermedia de crecimiento, sólo tiene que utilizar 'std :: vECTOR' - que crecerá de forma automática cuando es necesario y se puede pre-asignar memoria si quieres (' reserva() '). – sharptooth

+3

Utilizar std :: vector . Para eso es para eso. En C++, no hay ninguna razón para usar new/delete/new []/delete [] usted mismo, a menos que esté escribiendo explícitamente clases de gestión de recursos. – Puppy

29

El redimensionamiento en C++ es incómodo debido a la posible necesidad de llamar a constructores y destructores.

No creo que hay una razón fundamental por la cual en C++ no se podría tener un operador de resize[] ir con new[] y delete[], que hizo algo parecido a esto:

newbuf = new Type[newsize]; 
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf); 
delete[] oldbuf; 
return newbuf; 

Obviamente oldsize serían recuperados desde un lugar secreto, lo mismo está en delete[], y Type vendría del tipo del operando. resize[] fallaría donde el tipo no se pueda copiar, lo que es correcto, ya que dichos objetos simplemente no se pueden reubicar. Finalmente, el código anterior predeterminado: construye los objetos antes de asignarlos, lo que no le gustaría como el comportamiento real.

Hay una posible optimización en newsize <= oldsize, para llamar a los destructores de los objetos "pasados ​​el final" de la nueva matriz ensmallened y no hacer nada más.El estándar debería definir si esta optimización es necesaria (como cuando resize() un vector), permitido pero no especificado, permitido pero dependiente de la implementación, o prohibido.

La pregunta que debe hacerse entonces es: "¿es realmente útil proporcionar esto, dado que vector también lo hace, y está diseñado específicamente para proporcionar un contenedor redimensionable (de memoria contigua, ese requisito omitido en C++ 98 pero arreglado en C++ 03) que es un mejor ajuste que las matrices con las formas C++ de hacer las cosas? "

Creo que la respuesta es ampliamente cree que es "no". Si desea hacer un búfer redimensionable de la manera C, use malloc/free/realloc, que están disponibles en C++. Si desea hacer un búfer redimensionable al estilo C++, use un vector (o deque, si realmente no necesita almacenamiento contiguo). No intente mezclar los dos utilizando new[] para buffers sin formato, a menos que esté implementando un contenedor similar a un vector.

-4

intento algo así:

typedef struct Board 
{ 
    string name; 
    int size = 0; 
}; 

typedef struct tagRDATA 
{ 
    vector <Board> myBoards(255); 

    // Board DataBoard[255]; 
    int SelectedBoard; 

} RUNDATA; 

vector se quejará. Es por eso que todavía existen arreglos, malloc y nuevos.

+4

No, no es por eso. Y no veo cómo esto responde la pregunta de ninguna manera. O por qué estás usando 'typedef' en todas partes como si estuvieras escribiendo C. –

Cuestiones relacionadas