Verständnisfrage zu dynamischen Arrays
-
Hallo,
ich habe eine Verständnisfrage zu dynamischen Arrays:
int arrayGroesse; int *testfeld; printf("Feldgroesse eingeben: "); scanf("%d",&arrayGroesse); getchar(); testFeld = malloc(arrayGroesse * sizeof(int)); if(testFeld == NULL){ printf("hab kein speicher"); exit(1);
wieso mache ich das so wie ich es hier mache? Oder um die Frage ein wenig zu konkretisieren: Ich will ja ein Feld erzeugen, dessen Größe am Anfang noch nicht klar ist. Aber ich will doch ein Feld haben, wieso initialisiere ich aber einen Zeiger mit der gewünschten Größe mal Größe eines Integers? Das ich arrayGroesse * sizeof(int) nehme ist ja logisch, ich will x Zahlen von der jede Zahl y groß ist. Aber warum wir damit der Zeiger initialisiert? Was passiert dabei genau, auf Speicherebene usw.?! Wohin schiebt der Rechner was?1 Ich will genau verstehen warum ich das so und nicht anders schreibe, und was beim Rechner dabei im hintergrund abläuft, denn stupide Code auswendig lernen kann jeder
Bin sehr gespannt auf eure Antworten!
Grüße
chmbw
-
hi,
also dein Zeiger, sprich in deinem Falle testFeld speichert ja die Adresse des ersten Elements deines Arrays. Durch malloc erzeugst du ja den Speicher dynamisch (sprich im Heap.. weiß nicht ob dir Heap, Stack was sagt?) du adressierst dir also sozusagen den (vorläufig) benötigten Speicher mit malloc, damit du auf diesen auch zugreifen kannst, musst du ihn ja logischerweise irgendwo speichern, deshalb weißt du deinem Pointer diese Adresse zu.Klar könntest du auch einfach int testFeld[groesse] schreiben, aber diese größe kannst du dannn nicht mehr verändern, sondern die bleibt ein für alle Mal statisch (geht in den Stack), während wenn du malloc verwendest, du die Größe neu definieren kannst etc..
Achja, bevor du das exit(1) machst, schreib unbedingt:
free(testFeld);
das gibt den adressierten Speicher wieder frei
Hoffe ich hab deine Frage richtig verstanden?
lg
-
Hi,
erstmal herzlichen Dank für deine Antwort! Also mit malloc erzeuge ich ein Array im Heap, mit int testFeld[groesse] ein statisches Feld im Stack?!
Aber wenn ich jetzt meinen Speicherbereich addressiert habe, spreche ich den Addressierten Bereich also einfach wie ein Array an? Also IN DIESEM SEGMENT gehe jetzt zu bit 9 oder ähnlich (also testFeld[8] z.B.)?Ich bin mir allerdings nicht ganz sicher, ob ich inzwischen Stack und Heap wirklich verstanden habe, ich komme irgendwie noch mit Registern usw. und was wo jetzt erzeugt wird / sitzt durcheinander.
Das, was im Stack gespeichert wird, existiert für die gesamte Laufzeit des Programms, globale Variablen, statische Arrays usw. Im Heap nur so lange, wie ich sie auch verwende, richtig? Wo sitzen denn Stack und Heap genau, bzw. wo allokieren sie ihren Speicher?! Ist der Stack nicht ebenso wie der Heap im RAM untergebracht, allerdings mit ihren eigenen Segmenten?
Falls ich vollkommen daneben liege, bitte klärt mich auf
Was genau ist dann der Unterschied zwischen Stack und Heap, wo werden sie erzeugt bzw. "sitzen sie"?
Ich habe das Problem, bis jetzt habe ich massig über den Stack gefunden in der Hinsicht, dass ich da fröhlich mit push und pop was draufpacken bzw. runternehmen kann, es einen schönen stackpointer gibt, das teil nach dem LIFO prinzip funktioniert usw. aber nicht wirklich wo er genau sitzt, das gilt auch besonders für den Heap.
-
soweit ich das jetzt verstanden hab, ist es os abhängig wo die genau sitzen, das was auf dem stack landet ist eigentlich nur für die zeit verfügbar in der du dich in der function befindest (von daher kann man schon sagen das dass was in der main() auf dem stack landet für das ganze programm verfügbar ist :p ), die sachen im heap bleiben da so lange bis du sie wieder frei gibst? heap und stack nutzen das gleiche segment?
lg lolo
-
also du kannst es dir so vorstellen:
ein integer sagen wir hat 32 bit. also 8 byte
das is auch das was sizeof(int) zurückgibt.jetz hast du dein speicher z.b. so ( adressen, jede 1 byte groß)
0x0000 0x0001 0x0002 0x0003 ...
0x0010 0x0011 0x....
0x0100 0x0101
..wenn du jetz nen pointer erstellst int*pointer; zeigt dieser am Anfang auf NULL (bzw sollte so initialisiert werden).
Wenn du jetz den Befehlpointer=malloc(3*sizeof(int);
aufrust, wird dem pointer eine adresse zugewiesen sagen wir 0x0000, und die nächsten 2 adressen gehören ihm auch (wegen 3*), d.h.
du besetzt damit 0x0000 0x0001 und 0x0002
Diese Adressen (vom RAM) kann jetz kein anderes programm oder sonst was verwenden nur noch dein pointer, d.h. wenn du jetz sagst
*pointer=3; dann shreibst du in die adresse 0x0000 eine 3. Wenn du jetz allerdings auf 0x0001 zugreifen willst machst du entweder;pointer++
dann zeigt der Pointer direkt auf 0x0001 oder
pointer[1] dann greifst du auf den Speicher zu.free(pointer);
musst du verwenden, da kein anderes programm auf die 3 speicherstellen zugreifen kann. D.h. wenn du z.b. eine Rekursive funktion hast und viel speicher reservierst kann es (ok für heutige verhältnisse eher weniger) aber es kann dazu kommen, dass du den ganzen arbeitsspeicher belegst und somit kein anderes programm mehr platz im arbeitsspeicher hat.
-
32 bit sind natürlich 4 byte-.- sorry es is früh am morgn!^^
-
und die adressen haben in dem fall 4 byte jede XD (zur erleichterten darstellung XD)
-
Hallo,
erstmal herzlichen Dank für eure Antworten, ich denke ich habe jetzt verstanden was bei dem dynamischen allokieren abgeht. was mich jetzt aber noch interessiert ist, was sind Stack und Heap GENAU? Wo sitzen sie, wo haben sie ihren Speicherbereich?
-
chmbw schrieb:
...ich denke ich habe jetzt verstanden was bei dem dynamischen allokieren abgeht. was mich jetzt aber noch interessiert ist, was sind Stack und Heap GENAU?...
das wiederspricht sich doch oder
lg lolo
-
nun, ich weiß nicht ob es sich widerspricht, denn das Prinzip wie das allokieren vonstatten geht ist doch, denke ich, klar:
ich weise einem pointer jetzt eben nicht einfach nur EINE Adresse zu, sondern einen Block an Adressen aus dem RAM und habe somit mein Feld. Das ist doch das Prinzip was dahinter steckt?!
hmm, jetzt wo ich drüber nachdenke...vllt widerspricht es sich doch in der hinsicht, dass ich einmal mehr hätte nachdenken müssen / die Beiträge genauer lesen müssen um zu merken, dass beide wahrscheinlich im RAM angesiedelt sind
Sorry, bin halt eben aus der Uni gekommen ^^