Frage

Ich habe eine einfache Funktion, bei der ein Array mit Größe deklariert je nach Parametern, int ist.

    void f(int n){
        char a[n];
    };

    int main() {
        return 0;
    }

Dieses Stück Code kompiliert fein auf GNU C ++ , aber nicht auf MSVC 2005.

Ich erhalte die folgenden Kompilierungsfehler:

    .\main.cpp(4) : error C2057: expected constant expression
    .\main.cpp(4) : error C2466: cannot allocate an array of constant size 0
    .\main.cpp(4) : error C2133: 'a' : unknown size

Was kann ich tun, um dies zu korrigieren?

(Ich bin daran interessiert, diese Arbeit mit MSVC, ohne die Verwendung von neuen / löschen)

War es hilfreich?

Lösung

Was Sie gefunden haben, es eine der Erweiterungen Gnu Compiler auf die Sprache C ++. In diesem Fall ist Visual C ++ ganz korrekt. Arrays in C ++ muss mit einer Größe definiert werden, die ein Kompilierung-Konstante Ausdruck ist.

Es gab eine Funktion C in 1999 Update hinzugefügt zu dieser Sprache mit variabler Länge Arrays genannt, wo diese legal ist. Wenn Sie einen C-Compiler finden, die C99 unterstützt, was nicht einfach ist. Aber diese Funktion ist nicht Teil des Standard-C ++, nicht wird es im nächsten Update zu dem C ++ Standard hinzugefügt gehen werden.

Es gibt zwei Lösungen in C ++. Die erste ist ein std :: Vektor zu verwenden, der zweite nur Operator new [] verwenden:

char *a = new char [n];

Während ich meine Antwort schrieb, veröffentlicht ein anderer einen Vorschlag _alloca zu verwenden. Ich würde dagegen sehr empfehlen. Sie würden nur ein Nicht-Standard werden Austausch, nicht tragbare Verfahren für einen anderen nur als Compiler-spezifisch ist.

Andere Tipps

Ihre Methode aus dem Stapel der Zuteilung ist eine g ++ Erweiterung. Zur Ermittlung des Äquivalents unter MSVC zu tun, müssen Sie _alloca verwenden:

char *a = (char *)_alloca(n);

Sie verwenden etwas, das kein Standard ist. Eigentlich ist es Standard-C, aber nicht C ++. Wie eigenartig ist das!

Erklären ein bisschen mehr, Laufzeit bemessen Stapel-Arrays sind nicht Teil von C ++, sondern sind Teil C99, dem neuesten Standard für C. Deshalb haben einige Compiler es bekommen, während andere nicht. Ich würde Verzichten Sie es empfehlen, Compiler Kompatibilitätsprobleme zu vermeiden.

Die alternative Implementierung der Funktionalität würde mit neuen und löschen, wie strager geschrieben.

Sie können neue / delete / freier Speicher auf dem Heap zugewiesen werden. Dies ist langsamer und möglicherweise fehleranfälliger als char [n], aber es ist nicht Teil des C ++ Standard noch traurig.

Sie können für die Verwendung von neuen [] boost der scoped Array-Klasse eine Ausnahme-sichere Methode verwendet. delete [] wird automatisch aufgerufen, auf a , wenn es den Bereich verlässt.

void f(int n) {
    boost::scoped_array<char> a(new char[n]);

    /* Code here. */
}

Sie können auch std :: vector und Reserve () einige Bytes:

void f(int n) {
    std::vector<char> a;
    a.resize(n);

    /* Code here. */
}

Wenn Sie tun char [n] verwenden möchten, kompilieren als C99-Code anstelle von C ++ Code.

Wenn Sie unbedingt Daten auf dem Stapel zuweisen aus irgendeinem Grund, die Verwendung _alloca oder _malloca / _freea, die Verlängerungen von MSVC Libs sind und so weiter.

variabler Länge Array wurde in C99 eingeführt. Es wird in gcc unterstützt, aber nicht msvc. Laut einer Person in MSVC Team, hat Microsoft keinen Plan diese Funktion in ihren C / C ++ Compiler zu unterstützen. Er schlug vor, std :: vector in diesen Fällen zu verwenden.

Beachten Sie, dass C99 nicht erfordert, dass das Array auf dem Stapel zugeordnet. Der Compiler kann es auf dem Heap zugewiesen werden. Allerdings ist gcc das Array auf dem Stack zugeordnet werden.

Normalerweise in C (mit Ausnahme von C99-Compiler wie andere haben darauf hingewiesen) und C ++, wenn Sie Speicher auf dem Stack zugeordnet werden sollen, die Größe von dem, was Sie zuordnen mögen, hat zum Zeitpunkt der Kompilierung bekannt sein. Lokale Variablen werden auf dem Stack zugeordnet, so ein Array, dessen Länge ist abhängig von einem Funktionsparameter zur Laufzeit gegen diese Regel verstößt. Klein ist richtig darauf zu hinweisen, dass mit dem ‚neuen‘ Betreiber eine Möglichkeit, dieses Problem zu lösen:


char *a = new char [n];

‚a‘ ist immer noch eine lokale Variable auf dem Stapel zugeordnet, sondern die ganze Reihe zu sein (die variable Länge hat), es ist nur ein Zeiger auf ein Array (was immer die gleiche Größe ist, und somit bei der Kompilierung bekannt Zeit). Das Array wird auf dem Heap zugewiesen, die in der Regel das Gegenstück des Stapels spielt -. Der Stapel für die Dinge mit einer Größe zum Zeitpunkt der Kompilierung bekannt ist, und der Haufen ist für Dinge mit einer Größe nicht zu einem Kompilierung bekannt

Wäre es sinnvoll sein, einen vector<> zu verwenden, anstatt ein Array? Oder, da Sie eine char * sind zu ersetzen, ein std::string? Diejenigen, funktionieren gut mit Laufzeit Sizing, obwohl es auch andere Gründe geben kann, sie nicht zu verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top