2010-04-30 19 views
16

Soy un poco nuevo para malloc y C en general. Quería saber cómo puedo, si es necesario, ampliar el tamaño de una matriz de tamaño fijo con malloc.C: expandir una matriz con malloc

Ejemplo:

#define SIZE 1000 
struct mystruct 
{ 
    int a; 
    int b; 
    char c; 
}; 
mystruct myarray[ SIZE ]; 
int myarrayMaxSize = SIZE; 
.... 
if (i > myarrayMaxSize) 
{ 
    // malloc another SIZE (1000) elements 
    myarrayMaxSize += SIZE; 
} 
  • el ejemplo anterior se debe dejar en claro lo que quiero lograr.

(Por cierto: Necesito esto para un intérprete que escribo: El trabajo con una cantidad fija de variables y en caso de que se necesitan más, sólo asignar de forma dinámica)

Respuesta

15

Uso realloc, pero hay que asigna la matriz con malloc primero. Lo estás asignando en la pila en el ejemplo anterior.

size_t myarray_size = 1000; 
    mystruct* myarray = malloc(myarray_size * sizeof(mystruct)); 

    myarray_size += 1000; 
    mystruct* myrealloced_array = realloc(myarray, myarray_size * sizeof(mystruct)); 
    if (myrealloced_array) { 
    myarray = myrealloced_array; 
    } else { 
    // deal with realloc failing because memory could not be allocated. 
    } 
+5

'x = realloc (x, newsize)' es una pérdida de memoria esperando a suceder. –

+0

Buen punto. He actualizado el código de ejemplo para manejar fallas de realloc. –

+0

'myarray = myrealloced_array)' debe ser 'myarray = myrealloced_array;' :) – Saul

6

No, no puede. No puede cambiar el tamaño de una matriz en la pila una vez que está definida: eso es lo que significa tamaño fijo. O una matriz global, ya sea: no está claro desde el ejemplo de código donde se define myarray.

Puede malloc una matriz de 1000 elementos, y luego cambiar el tamaño con realloc. Esto puede devolverle una nueva matriz, que contiene una copia de los datos de la anterior, pero con espacio adicional al final.

1

a) no utilizó malloc para crearlo, por lo que no puede expandirse con malloc. Hacer:

mystruct *myarray = (mystruct*)malloc(sizeof(mystruct) *SIZE); 

b) utilizar realloc (RTM) para hacerlo más grande

+1

RTM -> http://www.cplusplus.com/reference/cstdlib/realloc/ – Mawg

12

Desea utilizar realloc (como otros críticos han señalado ya). Pero, por desgracia, los otros críticos se han mostrado no cómo utilizar correctamente:

POINTER *tmp_ptr = realloc(orig_ptr, new_size); 
if (tmp_ptr == NULL) 
{ 
    // realloc failed, orig_ptr still valid so you can clean up 
} 
else 
{ 
    // Only overwrite orig_ptr once you know the call was successful 
    orig_ptr = tmp_ptr; 
} 

Es necesario utilizar tmp_ptr de modo que si realloc falla, no se pierde el puntero originales.

Cuestiones relacionadas