2010-01-31 13 views
17

La referencia realloc dice:¿Cómo actualizar otros punteros cuando realloc mueve el bloque de memoria?

La función puede mover el bloque de memoria a una nueva ubicación, en cuyo caso se devuelve el nueva ubicación.

¿Quiere decir que si hago esto:

void foo() { 

     void* ptr = malloc(1024); 

     unsigned char* cptr = (unsigned char*)ptr+256; 

     ptr = realloc(ptr, 4096); 
} 

continuación cptr puede ser válida si realloc mueve el bloque?

Si es así, hace la señal realloc de ninguna manera, que se moverá el bloque, por lo que yo puedo hacer algo para evitar cptr se convierta en no válida?

+0

Esta es una buena pregunta 1 de mí, ya que hacen hincapié en la realloc fundamental curva de aprendizaje que implica ... – t0mm13b

Respuesta

6

Sí, cptr pierde su validez como realloc mueve el bloque! Y no, no hay mención de señalización para decirle que está moviendo el bloque de memoria. Por cierto, su código parece dudoso ... siga leyendo ... vea mi answer a otra pregunta y lea el código con mucho cuidado sobre cómo usa realloc. El consenso general es que si usted hace esto:

 
void *ptr = malloc(1024); 

/* later on in the code */ 

ptr = realloc(ptr, 4096); 

/* BAM! if realloc failed, your precious memory is stuffed! */ 

la manera de moverse que es el uso de un puntero temporal y usar eso como se muestra:

 
void *ptr = malloc(1024); 

/* later on in the code */ 

void *tmp = realloc(ptr, 4096); 

if (tmp != null) ptr = tmp; 

Editar: Gracias Secure para señalar un gremlin que se arrastró cuando estaba escribiendo esto anteriormente.

+0

No es un código real, es solo algo para mostrar lo que iba a hacer. Entonces, ¿hay alguna manera de cambiar el tamaño de un bloque de memoria existente sin moverlo (o decirle al programa que no es posible?). Si llamo a realloc y tiene éxito moviendo el bloque, ¿es posible de alguna manera mantener válidas las direcciones antiguas, de modo que pueda "deshacer" el realloc? – zajcev

+0

¡No! No puedes hacer eso ... eso es dependiente del compilador/enlazador/tiempo de ejecución. Y no, no puedes mantener las direcciones antiguas ya que el montón se fragmentará a lo largo del curso y la duración del programa. En resumen, no puede precisar las direcciones antiguas ya que la esencia misma de los indicadores se basa en el direccionamiento dinámico ... y no, no puede deshacer el realloc ... – t0mm13b

+0

Este es el molde más inútil del valor de retorno de malloc I ' he visto alguna vez ¿Y por qué arrojas el retorno de malloc, pero no el retorno de realloc? – Secure

3

Sí.

mejor que puede hacer es comparar PTR antes y después de la reasignación, y ver si se ha movido. No debe asignar un puntero al valor de compensación, en su lugar debe almacenar el desplazamiento y luego indexar el operador original con él.

decir

En lugar de void* newPtr = ptr + 10; *newPtr = something;

Uso int new = 10; ptr[new] = something;

2

Sí, el cptr deja de ser válida si realloc mueve el bloque.

+0

lo de los gritos pero ayudó a obtener la respuesta corta más allá del requisito de longitud minumum. – bmargulies

4

Sí, cptr pierde su validez si realloc mueve el bloque.

No, no hay señal. Debería verificar el valor de retorno con respecto a la ubicación original ptr.

4

Esto viene un poco tarde, aunque la solución a este problema (que nadie ha mencionado) es no utilizar punteros en bloques asignados que deberán ser asignados. En su lugar, use compensaciones con valores enteros desde el puntero base o (mejor) use un tipo struct y elementos de miembro para abordar ubicaciones específicas en el objeto asignado.

+0

Me gustaría haberlo leído antes de escribir mi tarea actual. También creo que esto es parte de la respuesta al OP de zajcev, explicando qué puede hacer al respecto. – gone

Cuestiones relacionadas