C 컴파일 오류 : "변수 크기의 개체를 초기화 할 수 없습니다."


97

다음 코드에서 "Variable-sized object may not initialized"오류가 발생하는 이유는 무엇입니까?

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

David Rodriguez의 훌륭한 답변에서 지적했듯이 길이가 변수이면 memset이 필요하지만 length가 컴파일 시간 상수이면 명령문이 잘 컴파일됩니다.
Casey

2020 FFWD -enum {length = 0xF } ; int boardAux[length][length] = {0};
요리사 검투사

답변:


121

C99 컴파일러 (동적 크기 배열 지원)를 사용하고 있다고 가정합니다. 코드의 문제는 컴파일러가 변수 선언을 볼 때 배열에 얼마나 많은 요소가 있는지 알 수 없다는 것입니다 ( length컴파일 시간 상수가 아닌 컴파일러 오류에서 여기에서도 가정합니다 ).

해당 배열을 수동으로 초기화해야합니다.

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

나는 파벨의 답변 후 쓴 두 번째 질문에 대해,뿐만 아니라 이러한 목적의 malloc에 무엇을 사용할 수 있습니다
인 helloWorld

@helloWorld : 스택 할당 배열로 printf( "%d", boardAux[1][2] )잘 컴파일됩니다. 컴파일러는 크기를 알고 메모리에서 (1,2) 번째 요소가있는 위치를 알고 있습니다. 동적 할당을 사용하는 경우 배열은 1 차원이므로 직접 계산해야합니다.printf("%d", boardAux[ 1*length + 2 ])
David Rodríguez-dribeas

@AndreyT : memset콜 아웃 에서 오류를 지적 해 주셔서 감사 합니다. 방금 수정했습니다.
데이비드 로드리게스는 - dribeas

내가 설정 한 경우 이유는 C99 컴파일러에서이 에러가 발생합니까 lengthstatic? C ++ 14에서는 잘 작동합니다.
Muhamed Cicak

25

C 언어에서는 가변 길이 배열에 이니셜 라이저를 사용할 수 없기 때문에이 오류가 발생합니다. 당신이 얻는 오류 메시지는 기본적으로 모든 것을 말합니다.

6.7.8 초기화

...

3 초기화 할 엔티티의 유형은 알 수없는 크기의 배열이거나 가변 길이 배열 유형이 아닌 객체 유형이어야합니다.


이걸 어디서 찾았나요? 링크를 주 시겠어요?
인 helloWorld

1
@helloWorld : 이것은 언어 표준 (C99)에서 가져온 것입니다. 여기 open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
AnT

5
비공식적 인 설명 만 제공하면 항상 당신을 믿지 않는 주제가 있습니다. 가변 길이 배열은 이러한 주제 중 하나입니다. 표준 인용에 +1.
Pascal Cuoq

15

이것은 오류를 제공합니다.

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

이것은 또한 오류를 제공합니다.

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

그러나 이것은 잘 작동합니다.

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

다음과 같은 방식으로 가치를 입력해야합니다.

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

2

배열 선언 후

int boardAux[length][length];

초기 값을 0으로 할당하는 가장 간단한 방법은 약간 길어도 for 루프를 사용하는 것입니다.

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

2
memset더 간단하고 빠릅니다.
Cacahuete 프리 토

1

질문은 이미 답변되었지만 런타임에 길이가 변경되지 않는 경우 빠르고 작동하는 또 다른 솔루션을 지적하고 싶었습니다. main () 전에 매크로 #define을 사용하여 길이를 정의하고 main ()에서 초기화가 작동합니다.

#define length 10

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

매크로는 실제 컴파일 전에 실행되며 길이는 컴파일 시간 상수가됩니다 (David Rodríguez가 그의 답변에서 참조 함). 실제로 컴파일 전에 길이를 10으로 대체합니다.


0

길이를 단점으로 선언하기 만하면됩니다. 그렇지 않은 경우 메모리를 동적으로 할당해야합니다.


2
const가 무엇을 의미하는지 찾아봐야한다고 생각합니다!
Holger

@Holger : 확실합니까? 길이 (배열 자체가 아니라 배열 길이)를 보유하는 변수가 상수이면 컴파일러는 배열을 초기화하는 데 사용할 길이를 알고 있습니다. 예 : "int length = 5; int array [length];" 오류를 제공하지만 " const int length = 5; int array [length];" 잘 컴파일됩니다.
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
Stack Overflow에 오신 것을 환영합니다! : 좋은 답변을 작성하는 방법에 대한 설명서를 읽어 보시기 바랍니다 stackoverflow.com/help/how-to-answer 현재 답변이 모호한 것 같습니다과에 대한 설명이 없습니다
gybandi을

-5

C ++의 경우 이와 같은 별도의 선언 및 초기화 ..

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

1
아니 C ++ 질문
Cacahuete 프리 토

위는 전체 배열이 아닌 A [n] [m] 만 초기화합니다. int a [n] [m]; memset (a, 0, (n m sizeof (int)); // 배열의 mem 지우기 대부분의 컴파일러는 이것을 허용합니다 : int a [n] [m] = {0}; // 모든 멤버를 0으로 초기화
Chris Reid

-9

넌 못해. C 컴파일러는 스택에서 이러한 복잡한 일을 할 수 없습니다.

힙 및 동적 할당을 사용해야합니다.

정말로해야 할 일 :

  • 필요한 메모리의 크기 (n m sizeof (요소))를 계산 합니다.
  • malloc (size)를 호출하여 메모리를 할당합니다.
  • 접근자를 만듭니다 : int * access (ptr, x, y, rowSize) {return ptr + y * rowSize + x; }

* access (boardAux, x, y, size) = 42를 사용하여 행렬과 상호 작용합니다.


한 가지 더 질문, 지정되지 않은 범위를 가진 배열의 유효하지 않은 사용 오류가 발생하는 이유는 무엇입니까? printf ( "% d", 보드 [i] [j]);
helloWorld

10
-1 C99는 스택에서 사용자 코드로 동적 할당을 허용합니다 (초기화 제외). 동적 할당을 수행 할 필요가 없습니다.
데이비드 로드리게스는 - dribeas

@helloWorld는 배열 차원을 알아야하기 때문입니다.
Pavel Radzivilovsky
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.