Wenn ich ein Array auf dem Stapel zugewiesen habe, ist ein Zeiger auf das erste Element auch niedriger> im Wert als ein Zeiger auf das zweite Element?
Es ist nicht wichtig, "wie" Sie das Array zuweisen, Sie können den Stapelzeiger erhöhen oder verringern, aber als Ergebnis haben Sie Adressraum für das Array reserviert.
Sie können damit ganz normal arbeiten, da die niedrigste Adresse für Element 0 reserviert ist.
Meine Frage ist also, was das richtige Speicherlayout für einen Prozess in Linux ist.
Sie können es selbst überprüfen. Fügen Sie irgendwo in Ihr Programm etwas wie std::cin.get()
ein um Ihr Programm zu unterbrechen.
Dann in einer separaten Shell ausführen:
ps aux | grep your_program_name
cat /proc/<pid show by grep>/maps
Dies druckt die Speicherzuordnungen Ihres Prozesses, wo Sie sehen können, wo der Heap, der Stack und andere Dinge im Speicher abgelegt werden.
Über den Stack:Nehmen wir an, Sie haben einen normalen Computer mit Linux und Intel- oder AMD-64-Bit-CPU. Schreiben Sie dann den folgenden Code:
extern void f(int);
void g(int param)
{
f(param);
}
kompilieren und disassemblieren:
g++ -ggdb -c test_my_stack.cc && objdump -S test_my_stack.o
Sie können sehen (unwichtige Details entfernt):
void g(int param)
{
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 89 7d fc mov %edi,-0x4(%rbp)
f(param);
b: 8b 45 fc mov -0x4(%rbp),%eax
wie Sie in sub $0x10,%rsp
sehen können Wir haben Platz im Stapel reserviert, indem wir den Stapelzeiger verringert (nach unten bewegt) haben.
Das erste, was mich an diesem Bild gestört hat, ist, dass, wenn der Heap von hoch nach niedrig gewachsen ist, dann, wenn ich ein Array auf dem Heap zugewiesen habe, ein Zeiger auf das zweite Element einen kleineren int-Wert haben sollte als ein Zeiger auf das erste Element? das wäre verwirrend
Gar nicht. Nehmen wir an, Sie weisen ein Array von 10 Bytes aus einem Speicherpool zu, der von hoch nach niedrig wächst. Alles, was der Allocator tun müsste, ist, den "Boden" dieses Speicherpools um 10 zu dekrementieren und dann diesen Wert als Anfang des zugewiesenen Arrays zu verwenden. Das Array würde dann am alten "unten" enden. Die Zeigerarithmetik würde immer noch wie erwartet funktionieren, aber Sie würden in Richtung niedriger Adresse "wachsen".