Error de compilación de C: "Es posible que el objeto de tamaño variable no se inicialice"


97

¿Por qué recibo el error "Es posible que el objeto de tamaño variable no se inicialice" con el siguiente código?

int boardAux[length][length] = {{0}};

Como se señaló en la excelente respuesta de David Rodríguez: si la longitud es una variable, necesita memset, pero si la longitud es una constante en tiempo de compilación, entonces la declaración se compila bien.
Casey

ffwd a 2020 -enum {length = 0xF } ; int boardAux[length][length] = {0};
Chef Gladiator

Respuestas:


121

Supongo que está utilizando un compilador C99 (con soporte para matrices de tamaño dinámico). El problema en su código es que en el momento en que los compiladores ven su declaración de variable no pueden saber cuántos elementos hay en la matriz (también estoy asumiendo aquí, por el error del compilador quelength no es una constante de tiempo de compilación).

Debe inicializar manualmente esa matriz:

int boardAux[length][length];
memset( boardAux, 0, length*length*sizeof(int) );

También puedo usar malloc para este propósito, ¿qué pasa con la segunda pregunta? La escribí después de la respuesta de Pavel
helloWorld

@helloWorld: con matrices asignadas en pila, printf( "%d", boardAux[1][2] )compila bien. El compilador conoce los tamaños y sabe en qué posición en la memoria está el (1,2) -ésimo elemento. Si usa la asignación dinámica, la matriz es unidimensional y debe realizar las matemáticas usted mismo:printf("%d", boardAux[ 1*length + 2 ])
David Rodríguez - dribeas

@AndreyT: Gracias por señalar el error en la memsetllamada. Lo acabo de corregir.
David Rodríguez - dribeas

¿Por qué obtengo este error en el compilador C99 cuando configuro el lengthto be static? En C ++ 14 funciona bien.
Muhamed Cicak

25

Recibe este error porque en lenguaje C no se le permite utilizar inicializadores con matrices de longitud variable. El mensaje de error que está recibiendo básicamente lo dice todo.

6.7.8 Inicialización

...

3 El tipo de entidad que se va a inicializar será una matriz de tamaño desconocido o un tipo de objeto que no sea un tipo de matriz de longitud variable.


¿Dónde encontraste esto? ¿Puedes darme un enlace?
helloWorld

1
@helloWorld: Esto es del estándar de lenguaje (C99). Puede obtener una copia "funcional" con las actualizaciones de TC3
AnT

5
Hay temas por los que algunos siempre no te creerán si solo proporcionas una explicación informal. Las matrices de longitud variable son uno de estos temas. +1 por citar el estándar.
Pascal Cuoq

15

Esto da error:

int len;
scanf("%d",&len);
char str[len]="";

Esto también da error:

int len=5;
char str[len]="";

Pero esto funciona bien:

int len=5;
char str[len]; //so the problem lies with assignment not declaration

Necesita poner valor de la siguiente manera:

str[0]='a';
str[1]='b'; //like that; and not like str="ab";

2

Después de declarar la matriz

int boardAux[length][length];

La forma más sencilla de asignar los valores iniciales como cero es usar el bucle for, incluso si puede ser un poco largo

int i, j;
for (i = 0; i<length; i++)
{
    for (j = 0; j<length; j++)
        boardAux[i][j] = 0;
}

2
memsetes más sencillo y rápido.
Cacahuete Frito

1

La pregunta ya está respondida, pero quería señalar otra solución que es rápida y funciona si la longitud no debe cambiarse en tiempo de ejecución. Use la macro #define antes de main () para definir la longitud y en main () su inicialización funcionará:

#define length 10

int main()
{
    int boardAux[length][length] = {{0}};
}

Las macros se ejecutan antes de la compilación real y la longitud será una constante de tiempo de compilación (como lo menciona David Rodríguez en su respuesta). En realidad, sustituirá la longitud por 10 antes de la compilación.


0

Simplemente declare que la longitud es una desventaja, si no lo es, debería asignar memoria dinámicamente


2
¡Creo que necesitas buscar qué significa const!
Holger

@Holger: ¿Estás seguro? Si la variable que contiene la longitud (no la matriz en sí, sino la longitud de la matriz) es una constante, entonces el compilador conoce la longitud que debe utilizar para inicializar la matriz. Por ejemplo, "int longitud = 5; int matriz [longitud];" da el error pero " const int length = 5; int array [length];" se compila muy bien.
Casey

0
int size=5;
int ar[size ]={O};

/* This  operation gives an error -  
variable sized array may not be 
initialised.  Then just try this. 
*/
int size=5,i;
int ar[size];
for(i=0;i<size;i++)
{
    ar[i]=0;
}

1
¡Bienvenido a Stack Overflow! Lea la guía sobre cómo escribir una buena respuesta: stackoverflow.com/help/how-to-answer Su respuesta actual parece vaga y no tiene ninguna explicación
gybandi

-5

Para una declaración e inicialización separadas de C ++ como esta.

int a[n][m] ;
a[n][m]= {0};

1
No es una pregunta de C ++
Cacahuete Frito

Arriba solo inicializa A [n] [m], no la matriz completa. int a [n] [m]; memset (a, 0, (n m sizeof (int)); // borrar mem de la matriz La mayoría de los compiladores permiten esto: int a [n] [m] = {0}; // inicializar todos los miembros a 0
Chris Reid

-9

No puedes hacerlo. El compilador de C no puede hacer algo tan complejo en la pila.

Tienes que usar el montón y la asignación dinámica.

Lo que realmente necesitas hacer:

  • calcular tamaño (n m elemento)) de la memoria que necesita
  • llamar a malloc (tamaño) para asignar la memoria
  • crear un descriptor de acceso: int * acceso (ptr, x, y, rowSize) {return ptr + y * rowSize + x; }

Utilice * access (boardAux, x, y, size) = 42 para interactuar con la matriz.


una pregunta más, ¿por qué recibo un error de uso no válido de la matriz con límites no especificados? printf ("% d", tablero [i] [j]);
helloWorld

10
-1 C99 permite la asignación dinámica en la pila como código de usuario (excluyendo la inicialización). No es necesario realizar asignaciones dinámicas.
David Rodríguez - dribeas

@helloWorld porque las dimensiones de la matriz deben conocerse.
Pavel Radzivilovsky
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.