A. *_* H. 12 c++ linux memory-layout
我对程序在内存中的样子有点困惑,我的教授告诉我堆栈和堆在堆栈处于较低的内存地址时相互增长.
使用该映像困扰我的第一件事是,如果堆从高到低增长,那么如果我在堆上分配了一个数组,那么第二个元素的指针在int值中是否应该小于指向第一个元素的指针?这会令人困惑
我做了一点研究,我发现了这个数字(注意我的问题集中在linux上)
布局http://www.cyberplusindia.com/blog/wp-content/uploads/2008/10/memorysegment.gif
好吧,所以数据和未初始化的数据位于文本段之后,位于程序内存的开头,然后是堆后跟堆栈,最后是命令行参数和环境.
但是如果堆栈从高地址变为低,那么如果我在堆栈上分配了一个数组,那么如果我指向第一个元素的指针的值也会低于指向第二个元素的指针?这是不是意味着堆栈也会从低到高增长?
所以我的问题是Linux中进程的正确内存布局是什么?以及共享库的内存来自何处(在进程的地址空间中)
带指针示例的简单代码:
#include <iostream>
int data[5];
int main()
{
using std::cout;
using std::endl;
int stack = 0;
short *sptr = reinterpret_cast<short *> ( &stack );
int *iptr = new int[5];
cout << "Starting static tests"
<< "\nPointer to first element " << data
<< "\nPointer to second element " << &data[1]
<< "\nstarting stack test " << sptr
<< "\nsecond short " << &sptr[1]
<< "\nStarting heap test " << iptr
<< "\nsecond int " << &iptr[1];
delete[] iptr;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
Starting static tests
Pointer to first element 0x6013e0
Pointer to second element 0x6013e4
starting stack test 0x7fffdf864dbc
second short 0x7fffdf864dbe
Starting heap test 0x1829010
second int 0x1829014
Run Code Online (Sandbox Code Playgroud)
如果我在堆栈上分配了一个数组,那么指向第一个元素的指针的值也会低于指向第二个元素的指针?
“如何”分配数组并不重要,您可以增加或减少堆栈指针,但结果是为数组保留了地址空间。
您可以以正常方式使用它们,因为最低地址是为元素 0 保留的。
所以我的问题是 Linux 中进程的正确内存布局是什么?
你可以自己检查一下。在程序中的某个位置插入类似std::cin.get()暂停程序的内容。
然后在单独的 shell 中运行:
ps aux | grep your_program_name
cat /proc/<pid show by grep>/maps
Run Code Online (Sandbox Code Playgroud)
这会打印进程的内存映射,您可以在其中看到堆、堆栈和其他内容在内存中的位置。
关于堆栈:假设您有一台装有 Linux 和 Intel 或 AMD 64 位 CPU 的普通计算机。然后编写以下代码:
extern void f(int);
void g(int param)
{
f(param);
}
Run Code Online (Sandbox Code Playgroud)
编译并反汇编:
g++ -ggdb -c test_my_stack.cc && objdump -S test_my_stack.o
Run Code Online (Sandbox Code Playgroud)
可以看到(删除了不重要的细节):
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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,sub $0x10,%rsp我们通过减少(向下移动)堆栈指针来保留堆栈中的空间。