Warum erhalte ich mit dem folgenden Code die Fehlermeldung „Objekt mit variabler Größe kann nicht initialisiert werden“?
int boardAux[length][length] = {{0}};
Hallo Welt
Warum erhalte ich mit dem folgenden Code die Fehlermeldung „Objekt mit variabler Größe kann nicht initialisiert werden“?
int boardAux[length][length] = {{0}};
David Rodríguez – Dribeas
Ich gehe davon aus, dass Sie einen C99-Compiler verwenden (mit Unterstützung für Arrays mit dynamischer Größe). Das Problem in Ihrem Code ist, dass der Compiler zu dem Zeitpunkt, zu dem der Compiler Ihre Variablendeklaration sieht, nicht wissen kann, wie viele Elemente sich im Array befinden (ich gehe auch hier aufgrund des Compilerfehlers davon aus, dass length
ist keine Kompilierzeitkonstante).
Sie müssen dieses Array manuell initialisieren:
int boardAux[length][length];
memset( boardAux, 0, length*length*sizeof(int) );
Ich kann für diesen Zweck auch malloc verwenden, was ist mit der zweiten Frage, ich habe sie nach Pavels Antwort geschrieben
– Hallo Welt
21. Juni 2010 um 8:10 Uhr
@helloWorld: Mit Stack-zugewiesenen Arrays, printf( "%d", boardAux[1][2] )
kompiliert gut. Der Compiler kennt die Größen und weiß, an welcher Position im Speicher sich das (1,2)-te Element befindet. Wenn Sie die dynamische Zuordnung verwenden, ist das Array eindimensional und Sie müssen die Berechnung selbst durchführen: printf("%d", boardAux[ 1*length + 2 ])
– David Rodríguez – Dribeas
21. Juni 2010 um 8:39 Uhr
@AndreyT: Danke für den Hinweis auf den Fehler in der memset
aufbieten, ausrufen, zurufen. Ich habe es gerade korrigiert.
– David Rodríguez – Dribeas
21. Juni 2010 um 8:39 Uhr
Warum erhalte ich diesen Fehler im C99-Compiler, wenn ich die length
sein static
? In C++14 funktioniert es einwandfrei.
– Silidron
18. Dezember 2017 um 20:35 Uhr
Ich will den Grund dafür wissen malloc
ist nicht nötig.
– mazend
21. Oktober 2020 um 14:36 Uhr
Sie erhalten diesen Fehler, weil Sie in der Sprache C keine Initialisierer mit Arrays variabler Länge verwenden dürfen. Die Fehlermeldung, die Sie erhalten, sagt im Grunde alles.
6.7.8 Initialisierung
…
3 Der Typ der zu initialisierenden Entität muss ein Array unbekannter Größe oder ein Objekttyp sein, der kein Array-Typ mit variabler Länge ist.
Wo hast du das gefunden, kannst du mir einen Link geben?
– Hallo Welt
21. Juni 2010 um 8:11 Uhr
@helloWorld: Dies ist vom Sprachstandard (C99). Eine “funktionierende” Kopie mit TC3-Updates erhalten Sie hier open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
– AnT steht zu Russland
21. Juni 2010 um 8:13 Uhr
Es gibt Themen, bei denen Ihnen einige immer wieder nicht glauben werden, wenn Sie nur die informelle Erklärung liefern. Arrays mit variabler Länge sind eines dieser Themen. +1 für das Zitieren des Standards.
– Pascal Cuoq
21. Juni 2010 um 8:30 Uhr
@AnT Ich führe den Code in C++ aus, er wird gut kompiliert, also ist die Initialisierung eines Arrays mit variabler Größe in C++ gültig?
– Abhishek Mähne
23. April 2021 um 3:50 Uhr
@Abhishek Mane: Nein. C++ hat einfach überhaupt keine Arrays mit variabler Größe.
– AnT steht zu Russland
23. April 2021 um 17:53 Uhr
Dies gibt Fehler:
int len;
scanf("%d",&len);
char str[len]="";
Dies gibt auch Fehler:
int len=5;
char str[len]="";
Aber das funktioniert gut:
int len=5;
char str[len]; //so the problem lies with assignment not declaration
Sie müssen den Wert wie folgt angeben:
str[0]='a';
str[1]='b'; //like that; and not like str="ab";
Nach der Deklaration des Arrays
int boardAux[length][length];
Der einfachste Weg, die Anfangswerte als Null zuzuweisen, ist die Verwendung einer for-Schleife, auch wenn dies etwas langwierig sein kann
int i, j;
for (i = 0; i<length; i++)
{
for (j = 0; j<length; j++)
boardAux[i][j] = 0;
}
Oskar Enoksson
Arrays mit variabler Länge sind Arrays, deren Länge dem Compiler zur Kompilierzeit nicht bekannt ist. In Ihrem Fall length
ist eine Variable. Ich schließe dies, denn wenn length
Wurde zB ein Präprozessor-Makro als wörtliche Ganzzahl definiert, würde Ihre Initialisierung funktionieren. Der erste C-Sprachstandard von 1989 erlaubte keine Arrays mit variabler Länge, sie wurden 1999 hinzugefügt. Der C-Standard erlaubt es immer noch nicht, diese mit einem Ausdruck wie Ihrem zu initialisieren (obwohl man argumentieren könnte, dass er dies zulassen könnte oder sollte).
Der beste Weg, ein Variablen-Array zu initialisieren, ist wie folgt:
int boardAux[length][length];
memset( boardAux, 0, sizeof(boardAux) );
memset
ist eine sehr schnelle Standardbibliotheksfunktion zum Initialisieren des Speichers (im obigen Fall auf 0). sizeof(boardAux)
gibt die Anzahl der belegten Bytes zurück boardAux
. sizeof
ist aber immer verfügbar memset
erfordert #include <string.h>
. Und ja – sizeof
erlaubt ein Objekt mit variabler Größe als Argument.
Beachten Sie, dass Sie, wenn Sie ein normales Array (nicht variable Länge) haben und den Speicher nur auf Null initialisieren möchten, niemals verschachtelte Klammern benötigen. Sie können es einfach wie folgt initialisieren:
struct whatEver name[13][25] = {0};
Das Array wird nicht mit dem angegebenen Speicher initialisiert und gibt einen Fehler aus
variable sized array may not be initialised
Ich bevorzuge die übliche Art der Initialisierung,
for (i = 0; i < bins; i++)
arr[i] = 0;
Sergej
Die Frage wurde bereits beantwortet, aber ich wollte auf eine andere Lösung hinweisen, die schnell ist und funktioniert, wenn die Länge nicht zur Laufzeit geändert werden soll. Verwenden Sie das Makro #define vor main(), um die Länge zu definieren, und in main() funktioniert Ihre Initialisierung:
#define length 10
int main()
{
int boardAux[length][length] = {{0}};
}
Makros werden vor der eigentlichen Kompilierung ausgeführt, und die Länge ist eine Kompilierzeitkonstante (wie von David Rodríguez in seiner Antwort erwähnt). Die Länge wird vor der Kompilierung tatsächlich durch 10 ersetzt.
gibt es einen wirklichen unterschied zw {0}
und {{0}}
?
– ITJ
2. November 2020 um 10:48 Uhr
Dadurch wird nicht wirklich ein Objekt mit variabler Größe erstellt.
– sagarjha
13. Mai 2021 um 8:10 Uhr
Wie in der hervorragenden Antwort von David Rodriguez ausgeführt: Wenn length eine Variable ist, benötigen Sie memset, aber wenn length eine Konstante zur Kompilierzeit ist, wird die Anweisung problemlos kompiliert.
– Casey
11. Februar 2020 um 19:17 Uhr
ffwd bis 2020 —
enum {length = 0xF } ; int boardAux[length][length] = {0};
– Chef Gladiator
7. August 2020 um 8:11 Uhr
macht es ein
const int
hat dieses Problem für mich gelöst.– Mote Zart
12. Februar 2021 um 18:58 Uhr
@MoteZart Tat es? Gegeben
const int length = 1; int boardAux[length][length] = {{0}};
boardAux
ist ein Array variabler Länge undlength
ist nicht ein konstanter Ausdruck. Denken Sie daran,const
bedeutet nur schreibgeschützt; es bedeutet nicht “konstant”. (length
wäre ein konstanter Ausdruck in C++, das keine Arrays mit variabler Länge unterstützt.)– Keith Thompson
21. September 2021 um 8:41 Uhr