Saltar al contenido

¿Cómo crear una matriz sin declarar el tamaño en C?

Solución:

C no admite matrices con un número dinámico de elementos. El número de elementos de una matriz debe determinarse en tiempo de compilación o ya que C99 se puede evaluar en tiempo de ejecución en el punto de creación. Una vez que se crea la matriz, su tamaño es fijo y no se puede cambiar. Hay algunos casos en los que el tamaño no se especifica explícitamente entre los [], ya sea en definiciones de matriz o en declaraciones de matriz.

Usted puede definir una matriz sin un tamaño explícito para la dimensión más a la izquierda si proporciona un inicializador. El compilador inferirá el tamaño del inicializador:

int a[] = { 1, 2, 3 };              // equivalent to int a[3] = { 1, 2, 3 };
int m[][2] = {{ 1, 2 }, { 3, 4 }};  // equivalent to int m[2][2] = {{ 1, 2 }, { 3, 4 }};
char s[] = "Hello worldn";         // equivalent to char s[13] = "Hello worldn";

Observe cómo el compilador agrega el terminador nulo implícito en el caso de la cadena.

Usted puede declarar una matriz sin un especificador de tamaño para la dimensión más a la izquierda en casos múltiples:

  • como una variable global con extern almacenamiento de clase (la matriz se define en otro lugar),
  • como parámetro de función: int main(int argc, char *argv[]). En este caso, el tamaño especificado para la dimensión más a la izquierda se ignora de todos modos.
  • como el último miembro de un struct con más de un miembro nombrado. Esta es una extensión C99 llamada matriz flexible.

El compilador no tiene información sobre el tamaño real de estas matrices. El programador usará alguna otra información para determinar la longitud, ya sea a partir de una variable separada o del contenido de la matriz.

En el caso de un argumento de función, la matriz se pasa como un puntero e incluso si se especifica el número de elementos, sizeof(argv) evalúa el tamaño de un puntero.

Podrías usar una combinación de malloc() (o calloc()), realloc() y free() lograr esto.

La memoria se puede asignar como bloques de un tamaño fijo en lugar de reasignar la memoria para cada número que se va a almacenar.

Definamos una macro (o una const Si te gusta) BLOCK_SIZE.

#define BLOCK_SIZE 10

Primero declare un puntero del tipo apropiado y asigne el primer bloque.

Tenga en cuenta que malloc() al igual que realloc() regreso NULL si se produjo algún error debido a razones como memoria insuficiente.

int *ptr=malloc(sizeof(int)*BLOCK_SIZE);    
if(ptr==NULL)
{
    perror("some error");
    return 1;
}

Ahora declare una variable para almacenar el índice máximo posible según la memoria asignada actualmente (para evitar el acceso ilegal a la memoria).

int max_index = BLOCK_SIZE-1;

Ahora usa un bucle.

for(int i=0; ; ++i)
{
    if(i > max_index)
    {
        ptr=realloc(ptr, (max_index+1 + BLOCK_SIZE)*sizeof(int));
        if(ptr == NULL)
        {
            perror("insufficient memory!");
            break;
        }
        printf("nRealloced!");
        max_index += BLOCK_SIZE;
    }
    scanf("%d", &ptr[i]);
    printf("n%d: %d", i, ptr[i]);
}

En cada iteración, comprobamos si i es mayor que max_index. Si es así, se asigna otro bloque usando realloc() antes de leer el valor.

No olvide desasignar la memoria una vez que haya terminado de usarla.

free(ptr);

Además, como se discutió en esta publicación, malloc() es efectivamente lo mismo que realloc() con el primer argumento de este último NULL.

Y en el código que publicó, no es necesario emitir explícitamente el valor de retorno de calloc() ya que lo que se devuelve es un void puntero que se convertiría implícitamente en el tipo de puntero de destino.

Vea esto y esto.

No declaras una matriz sin un tamaño, sino que declaras un puntero a varios registros.

entonces, si quisieras hacer

int bills[];

La forma correcta de hacer esto en C es

int* bills;

Y tendrá que asignar el tamaño en algún momento e inicializar la matriz.

bills = (int*)malloc(sizeof(int)*items);

Lo mismo ocurre con las matrices de otros tipos de datos. Si no conoce el tamaño de la matriz hasta el tiempo de ejecución, debe usar punteros a la memoria asignada al tamaño correcto en el tiempo de ejecución.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *