C derleme hatası: "Değişken boyutlu nesne başlatılamayabilir"


100

Neden aşağıdaki kodla "Değişken boyutlu nesne başlatılamayabilir" hatasını alıyorum?

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

David Rodriguez'in mükemmel yanıtında belirtildiği gibi: uzunluk bir değişkense, memset'e ihtiyacınız var, ancak uzunluk bir derleme zamanı sabiti ise, o zaman ifade gayet iyi derlenir.
Casey

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

Yanıtlar:


126

Bir C99 derleyicisi kullandığınızı varsayıyorum (dinamik boyutlu diziler için destekle). Kodunuzdaki sorun, derleyiciler değişken bildiriminizi gördüğünde, dizide kaç öğe olduğunu bilememesidir (burada ayrıca derleyici hatasından lengthderleme zamanı sabiti olmayan varsayıyorum ).

Bu diziyi manuel olarak başlatmalısınız:

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


@helloWorld: Yığın ayrılmış dizilerle, printf( "%d", boardAux[1][2] )iyi derler. Derleyici boyutları bilir ve hafızadaki (1,2) -ci elemanın hangi konumda olduğunu bilir. Dinamik ayırma kullanıyorsanız, dizi tek boyutludur ve matematiği kendiniz yapmanız gerekir:printf("%d", boardAux[ 1*length + 2 ])
David Rodríguez - dribeas

@AndreyT: Çağrıda hatayı işaret ettiğiniz için teşekkürler memset. Az önce düzelttim.
David Rodríguez - dribeas

Ben ayarladığınızda neden C99 derleyici bu hata alıyorum lengtholmak static? C ++ 14'te iyi çalışıyor.
Silidrone

Neden mallocgerekli olmadığını bilmek istiyorum .
mazend

26

Bu hatayı, C dilinde değişken uzunluklu dizilere sahip başlatıcıları kullanmanıza izin verilmediğinden alırsınız. Aldığınız hata mesajı temelde her şeyi söylüyor.

6.7.8 Başlatma

...

3 Başlatılacak varlığın türü, bilinmeyen boyutta bir dizi veya değişken uzunluklu dizi türü olmayan bir nesne türü olmalıdır.


Bunu nerede buldun, bana bir bağlantı verebilir misin?
helloWorld

1
@helloWorld: Bu, dil standardından (C99). TC3 güncellemeleriyle "çalışan" bir kopyayı buradan open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
AnT

5
Sadece resmi olmayan bir açıklama yaparsanız, bazılarının sizi her zaman inkar edeceği konular vardır. Değişken uzunluklu diziler bu konulardan biridir. Standarttan alıntı yapmak için +1.
Pascal Cuoq

15

Bu hata verir:

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

Bu aynı zamanda hata verir:

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

Ama bu gayet iyi çalışıyor:

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

Aşağıdaki şekilde değer katmanız gerekir:

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

3

Diziyi bildirdikten sonra

int boardAux[length][length];

başlangıç ​​değerlerini sıfır olarak atamanın en basit yolu, biraz uzun olsa bile for döngüsünü kullanmaktır

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

2
memsetdaha basit ve daha hızlıdır.
Cacahuete Cum

3

Soru zaten cevaplandı, ancak hızlı olan ve çalışma zamanında uzunluk değiştirilmek istenmiyorsa işe yarayan başka bir çözüme işaret etmek istedim. Uzunluğu tanımlamak için main () 'den önce makro #define kullanın ve main () içinde ilklendirmeniz çalışacaktır:

#define length 10

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

Makrolar, gerçek derlemeden önce çalıştırılır ve uzunluk bir derleme zamanı sabiti olacaktır (cevabında David Rodríguez tarafından bahsedildiği gibi). Derlemeden önce uzunluğu 10 ile değiştirecektir.


{0}ve arasında gerçek bir fark var {{0}}mı?
ITJ

1

Dizi belirtilen bellekle başlatılmadı anf bir hata atıyor, variable sized array may not be initialised ben normal başlatma yöntemini tercih ediyorum,

for (i = 0; i <= bins; i++)
        arr[i] = 0;

0

Uzunluğu bir eksiler olarak beyan edin, eğer değilse, o zaman belleği dinamik olarak ayırmalısınız.


2
Sanırım const'ın ne anlama geldiğine bakmanız gerekiyor!
Holger

@Holger: Emin misin? Uzunluğu tutan değişken (dizinin kendisi değil, dizi uzunluğu) sabitse, derleyici diziyi başlatmak için kullanılacak uzunluğu bilir. Örneğin, "int uzunluk = 5; int dizi [uzunluk];" hata verir ancak " const int length = 5; int array [length];" iyi derler.
Casey

@Casey: ama const int lenght=5; int array[length][length] = {{0}};olmayacak.
MestreLion

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'a hoş geldiniz! Lütfen iyi bir yanıtın nasıl yazılacağına ilişkin kılavuzu okuyun: stackoverflow.com/help/how-to-answer Mevcut yanıtınız belirsiz görünüyor ve herhangi bir açıklaması yok
gybandi

-5

C ++ için ayrı bildirim ve bunun gibi başlatma ..

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

1
C ++ sorusu değil
Cacahuete Frito

Yukarıda, tüm diziyi değil, yalnızca A [n] [m] 'yi başlatır. int bir [n] [m]; memset (a, 0, (n m sizeof (int)); // dizinin belleğini temizle Çoğu derleyici buna izin verir: int a [n] [m] = {0}; // tüm üyeleri 0 olarak
başlat

-9

Bunu yapamazsın. C derleyicisi yığın üzerinde böyle karmaşık bir şey yapamaz.

Yığın ve dinamik ayırma kullanmanız gerekir.

Gerçekten yapmanız gerekenler:

  • ihtiyacınız olan belleğin hesaplama boyutu (n m sizeof (element))
  • belleği ayırmak için malloc (boyut) çağrısı
  • bir erişimci oluşturun: int * erişim (ptr, x, y, rowSize) {return ptr + y * rowSize + x; }

Matrisle etkileşim kurmak için * access (boardAux, x, y, size) = 42 kullanın.


bir soru daha, neden tanımlanmamış sınırlara sahip geçersiz dizi kullanım hatası alıyorum? printf ("% d", kart [i] [j]);
helloWorld

10
-1 C99, kullanıcı kodu olarak yığında dinamik ayırmaya izin verir (başlatma hariç). Dinamik ayırmalar yapmaya gerek yoktur.
David Rodríguez - dribeas

@HelloWorld çünkü dizi boyutlarının bilinmesi gerekiyor.
Pavel Radzivilovsky
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.