Array-Größe zur Laufzeit ohne dynamische Zuordnung ist zulässig?
Lesezeit: 4 Minuten
syaz
Ich benutze C++ seit ein paar Jahren und heute habe ich Code gesehen, aber wie kann das vollkommen legal sein?
int main(int argc, char **argv)
{
size_t size;
cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
cout << i << endl;
}
return 0;
}
Kompiliert unter GCC.
Wie kann die Größe zur Laufzeit ermittelt werden ohne new oder malloc?
Nur um es noch einmal zu überprüfen, ich habe einige gegoogelt und alle ähnlichen Codes wie meine geben angeblich einen Speichergrößenfehler an.
Sogar Deitels C++ How To Program p. 261 Zustände unter Common Programming Error 4.5:
Nur Konstanten können verwendet werden, um die Größe von automatischen und statischen Arrays anzugeben.
Erleuchte mich.
Beachten Sie, dass DMA “direkter Speicherzugriff” bedeutet – ich denke, Sie fragen nach dynamischer Zuordnung
– anon
10. April 2009 um 10:32 Uhr
C oder C++? Wählen ein.
– Leichtigkeitsrennen im Orbit
9. April 2015 um 20:40 Uhr
Wählen Sie wieder eine aus: C oder C++. Diese Frage bezieht sich explizit und nur auf C; Es sollte kein C++-Tag vorhanden sein.
– Nik
10. Mai 2016 um 12:36 Uhr
Siehe auch Warum sind Arrays variabler Länge nicht Teil des C++-Standards?
– Wadzim
7. November 2018 um 13:32 Uhr
mmx
Dies gilt in C99.
Der C99-Standard unterstützt Arrays variabler Größe auf dem Stack. Wahrscheinlich hat sich auch Ihr Compiler dafür entschieden, dieses Konstrukt zu unterstützen.
Beachten Sie, dass dies anders ist als malloc und new. gcc weist das Array auf dem Stack zu, genau wie bei int array[100] indem Sie einfach den Stapelzeiger anpassen. Es erfolgt keine Heap-Zuordnung. Es ist ziemlich ähnlich _alloca.
Ich bin auf dasselbe Szenario in einer Datei in unserer Codebasis gestoßen, die vor Monaten geschrieben wurde. Ich war ebenso wie der Rest des Teams verblüfft, warum es kompiliert wurde. In unserer Situation wurde die Größe des Arrays berechnet, bevor das Array auch deklariert wurde (was auch nicht erlaubt sein sollte?). Jedenfalls ging eine Herausforderung aus. Wer beantworten kann, warum das legal ist, bekommt ein Pop-Tart. Wenn Sie jemals in Seattle sind, lassen Sie es mich wissen. Ich habe ein Pop-Tart für dich.
– Jeff Lamm
12. Januar 2011 um 22:55 Uhr
Können Sie einige Informationen/Links zur internen Funktionsweise des Stacks in diesem Fall bereitstellen? Führt dies zu einem gewissen Overhead in der Laufzeit?
– Balki
6. Juli 2011 um 11:21 Uhr
@balki Der Overhead ist gering, da er im Grunde den Stapelzeiger erhöht/verringert. Das Stapelverhalten kann im Wesentlichen identisch mit dem Normalfall sein, wenn Sie den ursprünglichen Stapelzeiger am Anfang der Funktion speichern.
– mmx
6. Juli 2011 um 19:31 Uhr
ist das in C++ erlaubt? Visual Studio lässt dies nicht zu?
– Justpraveen
10. Januar 2015 um 16:22 Uhr
Dies ist als VLAs (Arrays mit variabler Länge) bekannt. Es ist Standard in c99, aber gcc erlaubt es in C++-Code als Erweiterung. Wenn Sie möchten, dass der Code abgelehnt wird, versuchen Sie, mit zu experimentieren -std=standard, -ansi und -pedantic Optionen.
Die -std und -ansi Optionen haben überhaupt keinen Einfluss auf diese Erweiterung.
– Jonathan Wakely
13. Dezember 2018 um 12:38 Uhr
es ist gültig nur in C99. Beim nächsten Mal können Sie versuchen, Ihren Code in a zu überprüfen zuverlässiger Compiler.
Es ist gültiges C99, es ist kein gültiges C++. Dies ist einer von nicht wenigen Unterschieden zwischen den beiden Sprachen.
Verlies
Dieser Code läuft im GNU GCC Compiler.
#include<bits/stdc++.h>
int main(int argc, char **argv)
{
size_t size;
std:: cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
std:: cout << i;
}
return 0;
}
Najeeb
Sie können einem Array dynamisch Größe zuweisen, wenn Sie den Dev-Cpp-Compiler verwenden. Ich habe es ausprobiert und keinen Fehler erhalten, aber bei Visual C++- und Visual Studio-Compilern ist dies nicht möglich. Ich denke, der Grund ist, dass dev-c++ dem nicht initialisierten int eine positive Zahl zuweist und wenn wir ihr eine Zahl geben, wird sie durch die angegebene ersetzt. aber vielleicht geben andere Compiler nicht initialisierten Variablen null.
landerlyoung
Ich bin kürzlich auf ein Szenario gestoßen, in dem ein Stack-zugewiesenes Array gewünscht wird. (Es ist ein Wrapper um v8, der bei jedem Methodenaufruf ein Array von Argumenten benötigt).
Ein std::vector würde eine Heap-Speicherzuweisung vornehmen, deren Leistung nicht akzeptabel ist.
Hier ist meine Lösung, verwenden Sie die Vorlage, um ein Array von Fällen zuzuweisen:
template<size_t Argc>
static void call(...) {
v8::Local<v8::Value> v8Args[Argc];
// use v8Args
...
}
template<typename It>
static void callV8Function(size_t argc, It argvBegin, It argvEnd,) {
// C++ don't have dynamic stack allocation (like C99 does)
// try to avoid heap-allocation...
if (argc <= 4) {
return callV8FunctionOnStack<4>(...);
} else if (argc <= 8) {
return callV8FunctionOnStack<8>(...);
} else if (argc <= 16) {
return callV8FunctionOnStack<16>(...);
} else if (argc <= 32) {
return callV8FunctionOnStack< 32>(...);
} else {
std::vector<v8::Local<v8::Value>> v8Args(argc);
// fallback to vector
}
}
(Und natürlich kann ich auch mit einem Array der Größe 32 auskommen, aber das ist nicht so elegant.)
9961600cookie-checkArray-Größe zur Laufzeit ohne dynamische Zuordnung ist zulässig?yes
Beachten Sie, dass DMA “direkter Speicherzugriff” bedeutet – ich denke, Sie fragen nach dynamischer Zuordnung
– anon
10. April 2009 um 10:32 Uhr
C oder C++? Wählen ein.
– Leichtigkeitsrennen im Orbit
9. April 2015 um 20:40 Uhr
Wählen Sie wieder eine aus: C oder C++. Diese Frage bezieht sich explizit und nur auf C; Es sollte kein C++-Tag vorhanden sein.
– Nik
10. Mai 2016 um 12:36 Uhr
Siehe auch Warum sind Arrays variabler Länge nicht Teil des C++-Standards?
– Wadzim
7. November 2018 um 13:32 Uhr