Dynamisches Array
-
GhostfaceChilla schrieb:
Aber warum kann ich die Arrays so initialisieren? Braucht man nicht einen konstanten Ausdruck normalerweise?
Hmm, die Frage sollte eher lauten, wieso die Größe bei nicht-dynamischen Arrays überhaupt ein konstanter Ausdruck sein muss. In
Cist das ja vollkommen in Ordnung, wieso aber inC++nicht?
-
Warum?
C++ != CSollte aber ein alter Hut sein, diese Information.

-
out schrieb:
Und vergiß niemals
delete[].
Lieber RAII verstehen, ansonsten ist das eh nie exception sicher, auch wenn man nichts vergisst. (Da ist es schon wieder. :D)
GhostfaceChilla schrieb:
Aber warum kann ich die Arrays so initialisieren? Braucht man nicht einen konstanten Ausdruck normalerweise?
Ehm.. weil das.. für diesen Zweck.. da ist. Irgendwie, irgendwie ginge es aber auch anders. Insofern hat out schon recht.
out schrieb:
Hmm, die Frage sollte eher lauten, wieso die Größe bei nicht-dynamischen Arrays überhaupt ein konstanter Ausdruck sein muss. In C ist das ja vollkommen in Ordnung, wieso aber in C++ nicht?
Na ja, C89 kennt jetzt noch keine VLAs. Offen gesagt würde ich mir das für C++ auch nicht wünschen. Der Quatsch macht nur Ärger. Was ich allerdings tatsächlich vermisse ist alloca().
-
Aber warum kann ich die Arrays so initialisieren? Braucht man nicht einen konstanten Ausdruck normalerweise?
Wieso hat noch keiner gesagt, dass das VLAs ein GCC-Feature sind?
Edit²: Also, VL-Stackarrays, ne.
-
GhostfaceChilla schrieb:
Aber warum kann ich die Arrays so initialisieren? Braucht man nicht einen konstanten Ausdruck normalerweise?
ptr ist kein Array sondern ein Zeiger!
-
Sone schrieb:
Wieso hat noch keiner gesagt, dass das VLAs ein GCC-Feature sind?
Weil die Aussage falsch ist?
-
GhostfaceChilla schrieb:
Danke

Ja vector schon klar, aber wollte auch mal bisschen mit den Arrays rumprobieren
Aber warum kann ich die Arrays so initialisieren? Braucht man nicht einen konstanten Ausdruck normalerweise?-GhostfaceChilla-
Weil normale, micht mit new allozierte Speicherbereiche auf dem Stack angelegt werden, und zwar zu Compile-Zeit und nicht Laufzeit. Daher muss der Compiler vorher wissen, wie groß die einzelnen anzulegende Bereiche sein sollen -> konstanter Ausdruck, konstante und bekannte Größe.
Mit new allozierte Speicherbereiche werden auf dem Heap angelegt, zur Laufzeit. Daher interessiert es den Compiler zu Compile-Zeit nicht, wie groß dein Array ist.
-
truuth schrieb:
Sone schrieb:
Wieso hat noch keiner gesagt, dass das VLAs ein GCC-Feature sind?
Weil die Aussage falsch ist?
Ach halt die Klappe...
Haste meine Editierung nicht gesehen oder hast du nur keine Ahnung?
-
Sone schrieb:
truuth schrieb:
Sone schrieb:
Wieso hat noch keiner gesagt, dass das VLAs ein GCC-Feature sind?
Weil die Aussage falsch ist?
Ach halt die Klappe...
Haste meine Editierung nicht gesehen oder hast du nur keine Ahnung?Du lebst offensichtlich in C89. VLAs sind im C99-Standard dazugekommen. Also sind sie nicht ausschliesslich GCC-Feature. (In C11 sind sie de facto wieder rausgeflogen, aber damit sind sie immer noch Standard in C99.)
-
truuth schrieb:
Sone schrieb:
truuth schrieb:
Sone schrieb:
Wieso hat noch keiner gesagt, dass das VLAs ein GCC-Feature sind?
Weil die Aussage falsch ist?
Ach halt die Klappe...
Haste meine Editierung nicht gesehen oder hast du nur keine Ahnung?Du lebst offensichtlich in C89. VLAs sind im C99-Standard dazugekommen.
Schau mal hier, bei 8.3.4, direkt Klausel 1.
-
truuth schrieb:
Sone schrieb:
truuth schrieb:
Sone schrieb:
Wieso hat noch keiner gesagt, dass das VLAs ein GCC-Feature sind?
Weil die Aussage falsch ist?
Ach halt die Klappe...
Haste meine Editierung nicht gesehen oder hast du nur keine Ahnung?Du lebst offensichtlich in C89. VLAs sind im C99-Standard dazugekommen. Also sind sie nicht ausschliesslich GCC-Feature. (In C11 sind sie de facto wieder rausgeflogen, aber damit sind sie immer noch Standard in C99.)
Ich dachte, das wär hier das C++ Subforum. In C++ gibt es offiziell keine VLAs. Der GCC bietet das als Extension für C++ an. Aber dass sie in C11 "de facto wieder rausgeflogen" seien, ist mir neu. Interessant.

-
krümelkacker schrieb:
Aber dass sie in C11 "de facto wieder rausgeflogen" seien, ist mir neu. Interessant.

Habs mal für dich rausgekramt:
N1570 6.7.6.2 Klausel 4 schrieb:
Variable length arrays are a conditional feature that implementations need not support.
Wenn die Implementierung das Feature unterstützt, dann ist das folgende Makro definiert (als
1):__STDC_NO_VLA__
-
Yea schrieb:
Weil normale, micht mit new allozierte Speicherbereiche auf dem Stack angelegt werden, und zwar zu Compile-Zeit und nicht Laufzeit. Daher muss der Compiler vorher wissen, wie groß die einzelnen anzulegende Bereiche sein sollen -> konstanter Ausdruck, konstante und bekannte Größe.
Mit new allozierte Speicherbereiche werden auf dem Heap angelegt, zur Laufzeit. Daher interessiert es den Compiler zu Compile-Zeit nicht, wie groß dein Array ist.Ah ok,danke

-GhostfaceChilla-
-
Yea schrieb:
Weil normale, micht mit new allozierte Speicherbereiche auf dem Stack angelegt werden, und zwar zu Compile-Zeit und nicht Laufzeit. Daher muss der Compiler vorher wissen, wie groß die einzelnen anzulegende Bereiche sein sollen -> konstanter Ausdruck, konstante und bekannte Größe.
Mit new allozierte Speicherbereiche werden auf dem Heap angelegt, zur Laufzeit. Daher interessiert es den Compiler zu Compile-Zeit nicht, wie groß dein Array ist.Die Schlussfolgerung ist de facto aber falsch. Natürlich ist es auch möglich, den Stackzeiger mit erst zur Laufzeit bekannten Größen zu manipulieren. Es macht nicht mal nen Unterschied. Insofern ist eine technische Erklärung hier völlig fehl am Platz. Warum C++ sich dafür entschieden hat das nicht zu unterstützen, ist selbstverständlich am Typsystem festzumachen.
-
Artchi@logedOff schrieb:
Warum?
C++ != CSollte aber ein alter Hut sein, diese Information.

Ja, aber was haben sich die Leute, die den C++-Standard entwickeln, dabei gedacht? Es ist doch kaum Mehraufwand beim Compilerbau nicht-dynamische Arrays nicht-konstanter Größe zuzulassen. Und solange die Größe klein ist, wäre es sogar effizienter als einen std::vector bzw. ein new[]-Array zu erstellen.
Yea schrieb:
Weil normale, nicht mit new allozierte Speicherbereiche auf dem Stack angelegt werden, und zwar zu Compile-Zeit und nicht Laufzeit.
Das ist falsch oder du hast dich komisch ausgedrückt und meinst etwas anderes. Die nicht mit new allozierte Speicherbereiche werden doch erst zur Laufzeit auf den Stack gelegt und nicht schon vorher, denn es gibt ja sowas wie Rekursion. Es steht allerdings fest, um wie viel Bytes der Stackpointer verkleinert/vergrößert wird. Dieser Wert könnte aber (rein theoretisch) variabel sein. Allerdings kann man dann nicht beim Betreten einer Funktion wissen, um wie viel der Stack vergrößert wird, da dieser Wert erst berechnet werden muss.
-
Ramanujan schrieb:
Artchi@logedOff schrieb:
Warum?
C++ != CSollte aber ein alter Hut sein, diese Information.

Ja, aber was haben sich die Leute, die den C++-Standard entwickeln, dabei gedacht? Es ist doch kaum Mehraufwand beim Compilerbau nicht-dynamische Arrays nicht-konstanter Größe zuzulassen. Und solange die Größe klein ist, wäre es sogar effizienter als einen std::vector bzw. ein new[]-Array zu erstellen.
Letzteres stimmt, vorheriges ist Quatsch.
Ramanujan schrieb:
Yea schrieb:
Weil normale, nicht mit new allozierte Speicherbereiche auf dem Stack angelegt werden, und zwar zu Compile-Zeit und nicht Laufzeit.
Das ist falsch oder du hast dich komisch ausgedrückt und meinst etwas anderes. Die nicht mit new allozierte Speicherbereiche werden doch erst zur Laufzeit auf den Stack gelegt und nicht schon vorher, denn es gibt ja sowas wie Rekursion.
Ihr beide meint es wohl anders, denn deine Begründung ist ebenfalls Quatsch. Es gibt vor der "Laufzeit" oder der Ausführung der PE überhaupt keinen "Stack".
Ramanujan schrieb:
Dieser Wert könnte aber (rein theoretisch) variabel sein. Allerdings kann man dann nicht beim Betreten einer Funktion wissen, um wie viel der Stack vergrößert wird.
Soso, der Stack kann also vergrößert werden? Dann brauchen wir in C ja kein
mallocmehr,allocatuts schon
-
Sone schrieb:
Ramanujan schrieb:
Dieser Wert könnte aber (rein theoretisch) variabel sein. Allerdings kann man dann nicht beim Betreten einer Funktion wissen, um wie viel der Stack vergrößert wird.
Soso, der Stack kann also vergrößert werden? Dann brauchen wir in C ja kein
mallocmehr,allocatuts schon
Nein. An der Aussage von Ramanujan ist nichtmal was falsch. In der Tat kann der Stack vergrößert werden und das Betriebssystem arbeitet auch genau so. Zwar gibt man am Anfang an, wie groß der Stack maximal werden wird, das Betriebssystem alloziert trotzdem erst Stück für Stück die benötigten pages. Und natürlich gibt es noch weitere Unterschiede zwischen alloca und malloc, zum Beispiel weil alloca nur den aktuellen stackframe ändern kann und weil der Stack prinzipbedingt einige weitere Einschränkungen hat - zum beispiel das auf dem stack allozierter Speicher nicht länger existieren kann, als der Stackframe in dem er sich befindet.
//edit die Implementation von alloca und VLAs ist nicht einmal sonderlich komplex. Man muss den Stackframe anders aufbauen und zusätzlichen Aufräumcode erzeugen, aber das ist alles keine Magie. (ich kann allerdings nicht mehr beschreiben wie genau das ging, Sprachimplementierung ist ewig her, war aber einfach genug um vom Prinzip auf 2 Tafeln zu passen)
-
otze schrieb:
Sone schrieb:
Ramanujan schrieb:
Dieser Wert könnte aber (rein theoretisch) variabel sein. Allerdings kann man dann nicht beim Betreten einer Funktion wissen, um wie viel der Stack vergrößert wird.
Soso, der Stack kann also vergrößert werden? Dann brauchen wir in C ja kein
mallocmehr,allocatuts schon
Nein. An der Aussage von Ramanujan ist nichtmal was falsch. In der Tat kann der Stack vergrößert werden und das Betriebssystem arbeitet auch genau so. Zwar gibt man am Anfang an, wie groß der Stack maximal werden wird, das Betriebssystem alloziert trotzdem erst Stück für Stück die benötigten pages. Und natürlich gibt es noch weitere Unterschiede zwischen alloca und malloc, zum Beispiel weil alloca nur den aktuellen stackframe ändern kann und weil der Stack prinzipbedingt einige weitere Einschränkungen hat - zum beispiel das auf dem stack allozierter Speicher nicht länger existieren kann, als der Stackframe in dem er sich befindet.
o.O
Gut, da hab ich wohl viel zu tief gegriffen. Dachte, der Stack ist von vornherein so groß wie er immer ist (ca. 1 - 10 MB), aber anscheinend wäre das ja bei näherem überlegen auch reichlich bescheuert...?Edit: Doch das "(rein theoretisch)" kann er weglassen.
-
Ja, da ist auch etwas Magie dahinter, die auf den virtuellen Addresslisten der CPU basiert.
Das Programm selbst allokiert niemals Speicher für den Stack. Stattdessen wird ausgenutzt, dass die CPU eine Hardware-Exception schmeißt, wenn auf eine virtuelle Addresse zugegriffen wird, die nicht vergeben ist. Das Betriebssystem überprüft dann, ob die Addresse im Stackbereich liegt und wenn dies der Fall ist, wird eine weitere Page allokiert und auf der CPU dieser virtuelle Speicherbereich freigeschaltet.
Im Kontext dieses Threads meinte Ramanujan aber nur den Stackpointer, bzw den aktuellen Stackframe, der kann natürlich beliebig vergrößert werden, weil der Frame nur eine Datenstruktur ist, die das Programm bei Eintritt in zum Beispiel eine Funktion automatisch erzeugt. Und dort irgendwo einen Wert zu überschreiben und den Stackpointe rzu erhöhen ist kein Problem.
-
otze schrieb:
Im Kontext dieses Threads meinte Ramanujan aber nur den Stackpointer
Ja, genau. Meine Formulierung war leider etwas unpräzise.