2017-06-11 3 views
0

Ich lerne Speicherverwaltung von c-Programm. Ich bin zu einem guten Zweifel gekommen. (Ubuntu OS)malloc() | Unterschied in der Speicheradresslänge von Stapel- und Heapspeicherorten | C Programmierung

Mein Zweifel:

Ich wollte Adressen von Daten kennen, die in Stapel und innerhalb Haufen liegen beide. Aber als ich versuchte, diese Adressen zu drucken, habe ich festgestellt, dass die Länge der Adressen unterschiedlich ist! Frage ist, warum es Stack-Adresse mit mehr Länge als Heap-Adresse anzeigt?

Was ich weiß:

  • Stapelspeicher pro Prozess festgelegt ist und weniger als Heap-Speicher.
  • malloc() Speicher zuweisen auf Heap
  • lokale Variable geht auf Stapel

ich meine Demo-Code setzen hier so, dass Sie meine Zweifel gut beantworten kann.

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    int *ptr; // goes on stack 

    ptr = (int *)malloc(sizeof(int)); 
    *ptr = 10; // 10 is stored on heap 
    printf("%p : heap address\n",ptr); 
    printf("%p: stack address\n",&ptr); 
    return 0; 

} 

Ausgang: Ich habe folgende Ausgabe in meinem Terminal

0x1ea2010 : heap address 
0x7ffda62cb3c0: stack address 

So, jetzt können Sie verstehen, was ich zu fragen. Warum hat die Stapeladresse mehr Länge als der Heap? Heap ist ein großer Speicherpool, also sollte es offensichtlich mehr Länge haben.

Wenn Stack- und Heap-Zuweisung im selben Speicherblock erfolgt (wie bei modernen OS..Ich habe das irgendwo gelesen), so sollte es auch gleiche Länge haben.

Okay. Bitte helfen Sie mir, meine Gedächtniskonzepte klar zu machen.

Hinweis: Wenn meine Zweifel sehr einfach oder albern sind, dann lass mich bitte wissen, wie die Speicherzuweisung in meinem Demo-Code und Magie hinter verschiedenen Adresslängen erfolgt.

Danke für das Lesen solcher Post. Glückliche Antwort!

+0

Dies sind nur die virtuellen Adressen, die Sie ausdrucken. Die tatsächliche physikalische Adresse des Speichers kann aufgrund der dynamischen Verknüpfung nicht ermittelt werden. Jemand korrigiert mich bitte, wenn ich falsch liege. –

+0

Aus dem C-Standard über den Spezifizierer "% p" für den Konvertierungstyp: "Der Wert des Zeigers wird in eine Folge von Druckzeichen umgewandelt, ** in einer ** von der Implementierung definierten ** Art.". Und Sie sollten zwischen dieser Ausgabe und der internen Darstellung unterscheiden. Bitte geben Sie einen Verweis auf den Standard an, der erfordert, dass Stack-Adressen nicht größer als Heap-Adressen sein dürfen (oder es besteht eine Notwendigkeit für einen Stack oder einen Heap). – Olaf

+0

"Wenn Stapel- und Heap-Zuweisung im selben Speicherblock erfolgt (wie bei modernen OS .. Ich habe das irgendwo gelesen)" - glaube nicht alles, was einige obskure Seiten schreiben.Das macht keinen Sinn. Sie sollten den Autor um eine Klarstellung bitten. – Olaf

Antwort

1

Vorausgesetzt, dass Sie Ubuntu ausführen, nehme ich an, dass Sie auf einer x86 oder x86-64-Plattform ausgeführt werden. Unter der Annahme, das ist wahr, Ihr Programm Layout sieht wie folgt aus etwas:

   +-----------------------------+ 
High Address: | Command-line arguments | 
       | and environment variables | 
       +-----------------------------+ 
       |   Stack   | 
       |    |    | 
       |    V    | 
       |        | 
       |   ^   | 
       |    |    | 
       |   Heap    | 
       +-----------------------------+ 
       |  Uninitialized Data  | 
       +-----------------------------+ 
       |  Initialized Data  | 
       +-----------------------------+ 
       |  Program Text   | 
Low Address: |  (machine code)  | 
       +-----------------------------+ 

Der Stapel beginnt mit einer hohen Adresse und wächst „nach unten“ (in Richtung abnehmender Adressen), während der Haufen auf einer recht niedrige Adresse beginnt und wächst „nach oben "(Richtung zunehmende Adressen). Der %p Konvertierungsspezifizierer druckt die führenden Nullen in den Adresswerten nicht; wenn es so wäre, würde sich Ihre Adressen wie

0x0000000001ea2010: heap address 
0x00007ffda62cb3c0: stack address 

Beide Adressen wirklich die gleiche Länge haben, es ist nur, dass die führenden Nullen werden nicht angezeigt.

+0

Ich habe verstanden, was Sie vermitteln wollen. Ja, Längen sind die gleichen wie führende Nullen. – Parth

2

Es scheint, als ob Sie mit 64-Bit-Adressen arbeiten, was bedeutet, dass sie als bis zu 16 hexadezimale Zeichen ausdrucken. Sie sollten alle Adressen mit Nullen auf der linken Seite auffüllen, um 16 Zeichen zu erreichen.

0x0000000001ea2010: heap address 
0x00007ffda62cb3c0: stack address 

Der Haufen und Stapel (s) leben beide in dem gleichen virtuellen 2^64-Byte-Raum.

0

Es gibt keinen Standard.

Aber normalerweise passiert, dass Heaps nach oben wächst, während Stacks nach unten wächst. Daher wird Heap logisch am Anfangspunkt kleiner sein, während Stack größer ist.

Der Grund, warum eine solche Implementierung vorhanden ist, liegt darin, dass es einem Programm eine geringere Chance gibt, eine Überschneidung von statischem und dynamischem Speicher zu haben.

Jemand oben erwähnte virtuelle Adressen und physikalische Adressen.Kontextuell ist jedes Stück Speicher in einem Prozess eine virtuelle Adresse. Daher ist der Versuch, den BUDDY-Algorithmus zu erklären, im besten Fall eine Redundanz und im schlimmsten Fall irrelevant.

-1

Stellen Sie sich vor, Sie leben auf einer langen Straße. Sie wohnen am südlichen Ende der Straße, wo die Hausadressen 1, 2, 3 sind.

Stellen Sie sich vor, dass die Straße für eine Meile nach Norden verläuft. Stellen Sie sich vor, dass am nördlichen Ende der Straße die Adressen 998, 999, 1000 sind.

Stellen Sie sich vor, dass bis jetzt nur die Nord- und Südenden der Straße entwickelt worden sind. Von Adresse 20 bis Adresse 990 ist nichts als unbebaute Leerstellen.

Aber am Ende der Straße gibt es viel Aktivität. Neue Käufer kaufen Lose 20 bis 30 und bauen Häuser darauf.

In der Zwischenzeit, am nördlichen Ende der Straße, gibt es nicht so viel Aktivität. Es sieht so aus, als wären die Lose 989 und 990 verkauft worden, und dort wird etwas gebaut.

Also, wo gibt es einen größeren "Pool" von unbebauten Grundstücken? Am nördlichen oder südlichen Ende der Straße?

Bis jetzt gibt es am südlichen Ende der Straße (1-20, und wächst) mehr Häuser als am nördlichen Ende der Straße (990-1000). Bis jetzt ist das Wachstum auch am südlichen Ende der Straße schneller. (10 Lose im Bau am südlichen Ende, gegen 2 im Norden.)

Und doch sind die Adressen am nördlichen Ende der Straße größer (3 Ziffern beginnend mit 9 oder 4 Ziffern) als sie sind der Süden (2 Ziffern). Was bedeutet das? (Antwort: Das bedeutet eigentlich gar nichts.)

2

Ihre Format-Zeichenfolge in printf gibt an, führende Nullen zu überspringen, das ist die Standardeinstellung. Sie müssen die gewünschte Länge Ihrer gedruckten Adressen wie in% 016p,% 016x oder% 016X hinzufügen (wenn Sie hexadezimale Großbuchstaben verwenden möchten).

Wie Sie richtig annehmen, müssen alle Zeiger die gleiche Länge haben.

Verwandte Themen