Pregunta

Amigos

En nuestro C ++, Iam actual usando el método realloc para redimensionar la memoria asignada por malloc. el uso de realloc () se realiza de la siguiente manera

my_Struct *strPtr =(my_struct*)malloc(sizeof(my_Struct));

/* an later */

strPtr = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);

ahora wikipeadia (_http: //en.wikipedia.org/wiki/Malloc) dice que

Si en cambio uno lo hizo

void *p = malloc(orig_size);

/* and later... */

p = realloc(p, big_size);

entonces, en caso de que no sea posible obtener bytes de memoria de gran tamaño, p tendrá un valor NULL y ya no tendremos un puntero a la memoria previamente asignada para p, creando una pérdida de memoria

Y también dice que la forma correcta de rectificar el error anterior es

void *p = malloc(orig_size);

/* and later... */

void *tmp = realloc(p, big_size); 

if (tmp != NULL)
 {

p = tmp; /* OK, assign new, larger storage to p */

} 

else 

{

/* handle the problem somehow */

}

¿Puede decirme cuál es la mejor manera de usar realloc ()

también una vez que tengo un puntero a una estructura y luego, mientras uso realloc, ¿puedo usar el puntero a un vacío ???

Muchas gracias

¿Fue útil?

Solución

Por supuesto, debe protegerse contra el caso que realloc() devuelve NULL. Es una asignación de memoria, y en C (donde <=>) se usa principalmente, creo que los programadores de C ++ piensan que es un poco bajo nivel / qaint usar llamadas en bruto <=>, las asignaciones de memoria siempre pueden fallar.

Sobrescribir directamente el puntero con el valor de retorno es un error, ya que deja caer el puntero original y hace que la memoria pierda en caso de que falle la reasignación.

Otros consejos

Malloc () y realloc () son funciones de C. En realidad, realloc () hace malloc () y free () dependiendo de los argumentos que pase:

  • Si le pasa un puntero nulo, realloc hace lo que hace malloc.
  • Si pasa un tamaño cero, realloc hace lo que hace gratis.

Citado de Aquí , donde tiene una explicación más profunda.

La biblioteca de C hace que sea imposible expandir un bloque de memoria en su lugar, por lo que C ++ tampoco lo admite.

Si desea apegarse a las funciones de C, debe mantener el puntero de su primera asignación de memoria al llamar a realloc (). Luego verifica si es NULL, de lo contrario lo asigna, tal como lo hizo en su último código.

Pero quizás para C ++ la mejor solución es hacer su propio mallocator, la solución estándar basada en malloc de C (). Marque esto , o esto .

Utilice el enfoque sugerido & # 8211; mantenga el puntero al búfer anterior hasta que realloc haya regresado con éxito. Una vez que realloc () devuelve con éxito, el bloque anterior se ha liberado y todos los punteros a él se han colgado & # 8211; ajustarlos.

a realloc y malloc no les importa cuál es el tipo de puntero: puede usar void * así como cualquier cosa *.

Como han dicho otros, simplemente use realloc correctamente como se sugiere.

Pero la " forma C ++ " de hacer esto es realmente usar un std :: vector < > en lugar de mantener matrices usted mismo. De esa manera, la biblioteca estándar de C ++ se encargará de los detalles de bajo nivel de reasignación (presumiblemente mediante el uso de realloc ()).

Cuando realloc () falla y devuelve NULL, la memoria original queda intacta.
Entonces deberías usarlo así:

my_Struct* strPtr =(my_struct*)malloc(sizeof(my_Struct));

/* an later */

my_Struct* tmp = (my_struct*)realloc(strPtr,sizeof(my_Struct)*NBR);
if (tmp != NULL)
{
    strPtr = tmp;
}
else
{
    /* realloc Failed. Need to do something */
}

¿Por qué estás usando malloc y realloc? Casi siempre hay una mejor manera en C ++.

Si lo está utilizando para hacer matrices de longitud variable, es casi seguro que esté mejor con std :: vector < > ;, o tal vez una de las otras plantillas de contenedor.

Si en su lugar usa C, quizás con un compilador compatible con C ++, entonces la forma correcta es el segundo método, que no pierde un bloque de memoria completo cuando no se puede asignar.

La respuesta a su segunda pregunta también depende de si está utilizando C o C ++. En C, void * es un tipo de puntero de datos genérico y es libremente convertible. En C ++, void * debe convertirse explícitamente. Si realmente está escribiendo C, debe usar malloc () y amigos, que funcionan en void *. Si realmente está escribiendo C ++, necesita emitir, lo que lo hace más incómodo. En ninguno de los casos, realloc () funciona en punteros para estructurar, sino en punteros para anular.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top