Erro de compilação C: “Objeto de tamanho variável não pode ser inicializado”

97

Por que recebo o erro "Objeto de tamanho variável não pode ser inicializado" com o código a seguir?

int boardAux[length][length] = {{0}};
Olá Mundo
fonte
Como apontado na excelente resposta de David Rodriguez: se o comprimento for uma variável, você precisa do memset, mas se o comprimento for uma constante de tempo de compilação, então a instrução compila perfeitamente.
Casey
ffwd para 2020 -enum {length = 0xF } ; int boardAux[length][length] = {0};
Chef Gladiator

Respostas:

121

Presumo que você esteja usando um compilador C99 (com suporte para matrizes de tamanho dinâmico). O problema em seu código é que, no momento em que os compiladores vêem sua declaração de variável, não podem saber quantos elementos existem no array (também estou assumindo aqui, a partir do erro do compilador que lengthnão é uma constante de tempo de compilação).

Você deve inicializar manualmente essa matriz:

int boardAux[length][length];
memset( boardAux, 0, length*length*sizeof(int) );
David Rodríguez - dribeas
fonte
Eu posso usar para este propósito malloc também, e quanto à segunda pergunta, eu a escrevi após a resposta de Pavel
helloWorld
@helloWorld: Com arrays alocados na pilha, printf( "%d", boardAux[1][2] )compila bem. O compilador conhece os tamanhos e em que posição na memória está o (1,2) -ésimo elemento. Se você usar a alocação dinâmica, a matriz é unidimensional e você mesmo deve fazer as contas:printf("%d", boardAux[ 1*length + 2 ])
David Rodríguez - dribeas
@AndreyT: Obrigado por apontar o erro na memsetchamada. Acabei de corrigi-lo.
David Rodríguez - dribeas
Por que recebo este erro no compilador C99 quando defino o lengthcomo static? Em C ++ 14 funciona bem.
Muhamed Cicak
25

Você recebe este erro porque na linguagem C você não tem permissão para usar inicializadores com matrizes de comprimento variável. A mensagem de erro que você está recebendo diz basicamente tudo.

6.7.8 Inicialização

...

3 O tipo da entidade a ser inicializada deve obrigatoriamente ser um array de tamanho desconhecido ou um tipo de objeto que não é um tipo de array de comprimento variável.

Formiga
fonte
onde você encontrou isso, você pode me dar um link?
helloWorld
1
@helloWorld: Este é do padrão de linguagem (C99). Você pode obter um "trabalho" cópia com TC3 atualiza aqui open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
AnT
5
Existem assuntos para os quais alguns sempre não acreditarão em você se você fornecer apenas uma explicação informal. Matrizes de comprimento variável são um desses tópicos. 1 para citar o padrão.
Pascal Cuoq
15

Isso dá erro:

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

Isso também dá erro:

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

Mas isso funciona bem:

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

Você precisa colocar o valor da seguinte maneira:

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

Depois de declarar a matriz

int boardAux[length][length];

a maneira mais simples de atribuir os valores iniciais como zero é usando o loop for, mesmo que seja um pouco longo

int i, j;
for (i = 0; i<length; i++)
{
    for (j = 0; j<length; j++)
        boardAux[i][j] = 0;
}
Krishna Shrestha
fonte
2
memseté mais simples e rápido.
Cacahuete Frito
1

A questão já foi respondida, mas eu queria apontar outra solução que é rápida e funciona se o comprimento não deve ser alterado em tempo de execução. Use a macro #define antes de main () para definir o comprimento e em main () sua inicialização funcionará:

#define length 10

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

As macros são executadas antes da compilação real e a duração será uma constante de tempo de compilação (como referido por David Rodríguez em sua resposta). Na verdade, ele substituirá o comprimento por 10 antes da compilação.

Sergey
fonte
0

Simplesmente declare o comprimento como uma desvantagem, se não for, você deve alocar memória dinamicamente

Azizou
fonte
2
Eu acho que você precisa descobrir o que significa const!
Holger
@Holger: Tem certeza? Se a variável que contém o comprimento (não a matriz em si, mas o comprimento da matriz) for uma constante, o compilador saberá o comprimento a ser usado para inicializar a matriz. Por exemplo, "int length = 5; int array [length];" dá o erro, mas " const int length = 5; int array [length];" compila muito bem.
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;
}
Roubo de código
fonte
1
Bem-vindo ao Stack Overflow! Leia o guia sobre como escrever uma boa resposta: stackoverflow.com/help/how-to-answer Sua resposta atual parece vaga e não tem nenhuma explicação para ela
gybandi
-5

Para C ++, separe a declaração e a inicialização como esta.

int a[n][m] ;
a[n][m]= {0};
Munawir
fonte
1
Não é uma pergunta C ++
Cacahuete Frito
Acima inicializa apenas A [n] [m], não a matriz inteira. int a [n] [m]; memset (a, 0, (n m sizeof (int)); // limpar mem da matriz A maioria dos compiladores permite isso: int a [n] [m] = {0}; // inicializa todos os membros para 0
Chris Reid
-9

Você não pode fazer isso. O compilador C não pode fazer uma coisa tão complexa na pilha.

Você tem que usar heap e alocação dinâmica.

O que você realmente precisa fazer:

  • calcular o tamanho (n m sizeof (elemento)) da memória que você precisa
  • chame malloc (tamanho) para alocar a memória
  • crie um acessador: int * access (ptr, x, y, rowSize) {return ptr + y * rowSize + x; }

Use * access (boardAux, x, y, size) = 42 para interagir com a matriz.

Pavel Radzivilovsky
fonte
mais uma pergunta, por que recebo um erro de uso inválido de array com limites não especificados? printf ("% d", placa [i] [j]);
helloWorld
10
-1 C99 permite a alocação dinâmica na pilha como o código do usuário (excluindo a inicialização). Não há necessidade de realizar alocações dinâmicas.
David Rodríguez - dribeas
@helloWorld porque as dimensões do array precisam ser conhecidas.
Pavel Radzivilovsky