C-Kompilierungsfehler: “Objekt mit variabler Größe kann möglicherweise nicht initialisiert werden”

Lesezeit: 5 Minuten

Benutzeravatar von helloWorld
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}};

  • 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 und length 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

David Rodríguez - Benutzeravatar von dribeas
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;
}

Benutzeravatar von Oskar Enoksson
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;

Benutzeravatar von Sergey
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

1423490cookie-checkC-Kompilierungsfehler: “Objekt mit variabler Größe kann möglicherweise nicht initialisiert werden”

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy