wake-up-neo.com

speicherzuordnung in Stack und Heap

Dies mag eine sehr grundlegende Frage sein, aber es war in meinem Kopf so:

Wenn wir eine lokale Variable zuordnen, geht diese in den Stapel. Eine ähnliche dynamische Zuordnung bewirkt, dass die Variable auf Heap gespeichert wird. Nun, meine Frage ist, ob diese Variable tatsächlich auf Stack oder Heap liegt, oder wir werden nur eine Referenz in Stack und Heap sein.

Zum Beispiel,

Angenommen, ich deklariere eine Variable int i. Diese i ist jetzt auf dem Stack zugewiesen. Wenn ich also die Adresse von i drucke, ist dies eine Position auf dem Stapel? Gleiche Frage auch für Haufen.

17
Samir Baid

Ich bin nicht ganz sicher, was Sie fragen, aber ich werde mein Bestes geben, um zu antworten.

Im Folgenden wird eine Variable i auf dem Stack deklariert:

int i;

Wenn ich mit &i nach einer Adresse frage, erhalte ich die tatsächliche Position auf dem Stapel.

Wenn ich mit malloc etwas dynamisch zuweise, werden tatsächlichZWEIDatenstücke gespeichert. Der dynamische Speicher wird auf dem Heapspeicher und der Zeiger selbst auf dem Stapelspeicher zugewiesen. Also in diesem Code:

int* j = malloc(sizeof(int));

Dadurch wird Speicherplatz für eine ganze Zahl auf dem Heap reserviert. Es wird auch Platz auf dem Stack für einen Zeiger (j) zugewiesen. Der Wert der Variablen j wird auf die von malloc zurückgegebene Adresse gesetzt.

41
Chris Eberle

Hoffentlich ist folgendes hilfreich:

void foo()
{
    // an integer stored on the stack
    int a_stack_integer; 

    // a pointer to integer data, the pointer itself is stored on the stack
    int *a_stack_pointer; 

    // make a_stack_pointer "point" to integer data that's allocated on the heap
    a_stack_pointer = (int*)malloc(10 * sizeof(int));
}

Bei Stack-Variablen wird die Variable selbst (die tatsächlichen Daten) auf dem Stack gespeichert.

Im Fall von Heap allocation memory werden die zugrunde liegenden Daten immer auf dem Heap gespeichert. Ein Zeiger auf diesen Speicher/data kann lokal im Stack gespeichert werden.

Hoffe das hilft.

9
Darren Engwirda

Die Zeigervariable selbst würde sich auf dem Stapel befinden. Der Speicher, auf den der Zeiger zeigt, würde sich auf dem Heap befinden.

int *i = malloc(sizeof(int));

i würde sich auf dem Stack befinden, der tatsächliche Speicher, auf den ich auf *i verweise, würde sich auf dem Heap befinden.

5
Suroot

Ich stimme mit Chris überein. Nur eine andere Möglichkeit, das zu erklären. Betrachten Sie den folgenden Code:

int* j = malloc(sizeof(int));
free(j);

Selbst wenn free (j) verwendet wird, um den Speicher aus dem Heap freizugeben, ist der Zeiger immer noch vorhanden, und wir müssen ihn explizit NULL machen. Dies deutet definitiv darauf hin, dass es auch ein Stack-Gegenstück des Zeigers gibt, andernfalls sollte er nach dem Befehl free nicht vorhanden sein. Diese Stack-Variable zeigt auf die Adresse auf dem Heap, an der der Speicher dynamisch mit malloc zugewiesen wurde.

2
Prateek

Die Antwort von Herrn Eberle ist zu 100% korrekt, aber da Google dies als erste Antwort bei der Suche nach malloc heap or stack anzeigt, muss ich hinzufügen, dass malloc() Daten auf dem Heap meistens "zuordnet". Wenn die zugewiesenen Daten größer waren als MMAP_THRESHOLD , was normalerweise bei 32-Bit-Systemen 128 kb beträgt, wird malloc() not den Heap verwenden und stattdessen die Daten in einem Anonymer Speichersegment zuordnen. befindet sich normalerweise unter dem Stapel und wächst in Richtung des geringen Speichers.

Dies ist derselbe Bereich, in dem sich dynamisch geladene Bibliotheken befinden (libc.so usw.). Hier ist die relevante Passage aus man malloc :

Normalerweise reserviert malloc () Speicher vom Heap und passt die Größe Des Heaps mithilfe von sbrk (2) nach Bedarf an. Bei der Zuweisung von Blöcken Eines Speichers, der größer als MMAP_THRESHOLD-Bytes ist, ordnet die Implementierung der Glibc malloc () den Speicher mithilfe von mmap (2) als private anonyme Zuordnung zu. MMAP_THRESHOLD ist standardmäßig 128 kB, , Kann jedoch mit mallopt (3) eingestellt werden. Vor Linux 4.7 wurden die mit mmap (2) durchgeführten Zuordnungen von der Ressourcenbeschränkung RLIMIT_DATA nicht beeinflusst. seit Linux 4.7 wird diese Grenze auch für erzwungen, die mit mmap (2) vorgenommen werden.

Als praktisches Beispiel können Sie das nach dem Post überprüfen. Im Wesentlichen werden 300kb mit malloc() zugewiesen und anschließend pmap <PID> ausgeführt, um das relevante Speichersegment anzuzeigen.

0
Solidak

stack oder Heap sind kein separater Speicher, sie sind Speichersegmente, die ein laufendes Programm vom System zugewiesen hat, nur verschiedene Arten, um Daten im Speicher zu organisieren.

Wenn Sie also & i erhalten, handelt es sich um eine Speicheradresse, die so einfach ist.

0
Anh Pham