Wo werden Arrays gespeichert??
lima-city → Forum → Programmiersprachen → C/C++ und D
array
buffer
code
definieren
dynamisch speicher
erstellen
fehler
funktion
legen
option
pause
pointer
problem
speichern
standard
stelle
stichwort
system
wall
zeitpunkt
-
Hallo,
ich hab ein bissel rumexperimentiert und festgestellt, dass sich folgender Code problemlos mit gcc (Windows) compilieren und ausführen lässt.#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int i = 0; int n = 0; scanf("%d", &n); int array[n]; for (i = 0; i<n; i++){ array[i] = i; } for (i = 0; i<n; i++){ printf("%d \n", array[i]); } system("PAUSE"); }
Ich frage mich: Wo ist der Speicher für dieses Array? Warum funktioniert das überhaupt, dass man dynamisch Speicher alloziert ohne malloc zu benutzen? -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Der Speicherbereich eines Programms ist in 5 Sektionen aufgeteilt:
[Höchste Adresse]
-Betriebssystemspezifisches Zeug (readonly)
-Stack (variabler Inhalt und Größe)
-freier Speicher (variable Größe)
-Heap (variabler Inhalt und Größe)
-Code (readonly)
[Niedrigste Adresse]
Wenn du eine Variable deklarierst, dann wird diese auf dem Stack abgelegt.
Das heißt, der Stack wächst mit jeder Variable und nimmt sich den Speicherplatz eben aus dem Freien Speicher. Dabei ist zu beachten, dass der Stack wirklich wie ein "Stapel" geordnet ist. Also alles ist direkt übereinander im Speicher "gestapelt".
(Auch wenn der Stack von oben nach unten wächst ;) )
Dann haben wir noch den Heap, wo alle Variablen abgespeichert werden, die mit malloc() erzeugt werden. Der Heap, also der Haufen, ist, wie der Name schon vermuten lässt, nicht so streng geordnet wie ein Stack und die Daten liegen daher nicht in einer bestimmten Reihenfolge vor und es gibt Lücken zwischen den Speicherbereichen.
Der Heap wächst, indem er sich auch freien Speicher aus dem "freier Speicher"-Bereich besorgt.
Dadurch dass der Stack oben anfängt zu wachsen und der Heap unten im Speicher, treffen die beiden Bereiche bei Wachstum erst so spät wie überhaupt möglich aufeinander. Das ist sinnvoll, da beide Bereiche sich am gleichen "freien Speicher" bedienen. Aber jeder fängt an an einem anderen Ende an, sich das zu holen, was er braucht. -
Aber die Größe des Stacks ist stark begrenzt oder?
Oder anders gefragt: Wofür braucht man überhaupt den Heap? -
Man kann übrigens sogar folgendes ohne Probleme kompilieren:
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int i = 0; int n = 0; scanf("%d", &n); int array[n]; for (i = -5; i<(n+5); i++){ array[i] = i; } for (i = -5; i<(n+5); i++){ printf("%d n", array[i]); } system("PAUSE"); }
Man beachte, dass die Arraygrenzen sowohl beim Lesen als auch beim Schreiben ignoriert werden. Sogar negative Indizies funktionieren. -
willst du damit sagen, dass wenn ich es so mache, gar kein Speicher alloziert wurde und ich uU Probleme bekomme?
-
Nein, will ich nicht. Es wird schon Speicher alloziert. Auch wenn es eigentlich gegen den ISO Standard ist ein Array mit einer Variable als Größe zu definieren (Kompiliere mal mit den Optionen '-Wall -pedantic', dann siehst du die entsprechenden Warnings).
Aber die Arraygrenzen werden genauso ignoriert, wenn das Array z. B. mit int array[10] erzeugt wurde. C kümmert sich einfach nicht selbst um Arraygrenzen, dass musst du selbst überprüfen. (Stichwort Buffer Overflow) -
kochmarkus schrieb:
aber in meinem Code ist ein Buffer-Overflow ausgeschlossen, oder habe ich iwo einen Fehler gemacht?
Nein, will ich nicht. Es wird schon Speicher alloziert. Auch wenn es eigentlich gegen den ISO Standard ist ein Array mit einer Variable als Größe zu definieren (Kompiliere mal mit den Optionen '-Wall -pedantic', dann siehst du die entsprechenden Warnings).
Aber die Arraygrenzen werden genauso ignoriert, wenn das Array z. B. mit int array[10] erzeugt wurde. C kümmert sich einfach nicht selbst um Arraygrenzen, dass musst du selbst überprüfen. (Stichwort Buffer Overflow)
ich finde es nur interessant, dass man ohne malloc dynamisch Speicher allozieren kann. Wofür braucht man dann überhaupt malloc?
Aber die Arraygrenzen werden genauso ignoriert, wenn das Array z. B. mit int array[10] erzeugt wurde. C kümmert sich einfach nicht selbst um Arraygrenzen, dass musst du selbst überprüfen. (Stichwort Buffer Overflow)
-
aber in meinem Code ist ein Buffer-Overflow ausgeschlossen, oder habe ich iwo einen Fehler gemacht?
Ich denke du dürftest keine Probleme bekommen
ich finde es nur interessant, dass man ohne malloc dynamisch Speicher allozieren kann. Wofür braucht man dann überhaupt malloc?
Wie gesagt ist diese Methode ein Array anzulegen nicht ISO Konform, der gcc und wahrscheinlich auch andere Compiler beherrschen es jedoch (inzwischen). Der "richtigere" Weg wäre also malloc.
-
ich finde es nur interessant, dass man ohne malloc dynamisch Speicher allozieren kann. Wofür braucht man dann überhaupt malloc?
Die Sachen, die auf dem Heap gespeichert sind, werden nicht automatisch wieder gelöscht.
int foo(int zahl) { int b=2; //mach irgendwas tolles return 0; } int a=1; int c=foo(5); a=b;//funktioniert nicht
Zunächst wird die Variable a auf den Stack gelegt, danach kommt ein Funktionsaufruf, der ebenfalls Dinge auf dem Stack legt. Und zwar einmal die Rücksprungadresse (also die Stelle im Binärcode, wo der Funktionsaufruf stattgefunden hat + 1) und alle Parameter, die der Funktion übergeben werden, also in diesem Fall die 5.
Jetzt (wir sind in der Funktion) legen wir die Variable b auf den Stack und machen was tolles.
Wenn wir jetzt aber mit der Funktion fertig sind, wird der Stack bis zu der Stelle abgebaut, wo die Rücksprungadresse steht. Dann wird im Code zurückgesprungen und die Variablen, die innerhalb der Funktion definiert wurden, sind verloren.
Deswegen geht a=b; nicht, weil b zu dem Zeitpunkt nicht mehr existiert.
Der Stack räumt eben selber auf. In den meisten Fällen ist das wünschenswert, aber wenn man auf Variablen angewiesen ist, die innerhalb einer Funktion erzeugt werden, dann muss man mit malloc arbeiten und nen pointer auf den allozierten Speicher zurückgeben. -
OK, ich denke, ich habe es jetzt verstanden. Vielen Dank.
-
Wenn du dynamisch array erstellen willst, kannst du das aber besser so machen..:
#include <stdio.h> #include <stdlib.h> int* newsize( int* old, int sizeold, int sizenew) { int* tmp = new int[sizenew]; for(int i = 0; i < sizeold && i < sizenew; i++) { tmp[i] = old[i]; } delete [] old; return tmp; } int main(int argc, char *argv[]) { int i = 0; int n = 0; scanf("%d", &n); int* array = new int[n]; // int-pointer namens array erstellen system("PAUSE"); array = newsize(array, n, n+10); system("PAUSE"); delete [] array; //array löschen.. (Löscht nicht "array", das ist nur ein pointer) system("PAUSE"); }
wenn du den code nicht verstehst, beschäftige dich mal genauer mit pointern
-
das ist C++, vercetti. Hier geht es um C.
-
oh, entschuldigung^^ beim nächsten mal lese ich genauer^^
wobei ich auf den unterschied eh nicht so genau achte^^
Beitrag geändert: 3.11.2008 21:00:37 von vercetti -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage