在linux中的程序内存布局

我对一个程序在内存中的表现有些困惑,我的教授告诉我堆栈和堆栈正朝着彼此成长,而堆栈的内存地址较低。

首先让我困扰的是,如果堆从高到低,那么如果我在堆上分配一个数组,不应该使用指向第二个元素的指针小于指向第一个元素的指针的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;
}

输出:

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

如果我在栈上分配了一个数组,那么指向第一个元素的指针也会比指向第二个元素的指针更低> in的值?

如何分配数组并不重要,您可以增加或减少堆栈指针,但结果是为数组保留了地址空间。

您可以用正常的方式处理它们,因为最低地址是为元素0保留的。

所以我的问题是Linux中一个进程的正确内存布局是什么?

你可以自己检查一下。 在某处插入程序,如std::cin.get()来暂停程序。

然后在单独的shell中运行:

ps aux | grep your_program_name
cat /proc/<pid show by grep>/maps 

这将打印进程的内存映射,您可以在其中查看堆,堆栈和其他内容在内存中的位置。

关于堆栈:假设您拥有Linux和Intel或AMD 64位CPU的普通机器。 然后编写下面的代码:

extern void f(int);

void g(int param)
{
    f(param);
}

编译和反汇编:

g++ -ggdb -c test_my_stack.cc  && objdump -S test_my_stack.o

你可以看到(删除了不重要的细节):

 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

正如你可以在sub $0x10,%rsp看到的那样sub $0x10,%rsp通过减少(向下移动)堆栈指针来保留堆栈中的空间。


首先让我困扰的是,如果堆从高到低,那么如果我在堆上分配一个数组,不应该使用指向第二个元素的指针小于指向第一个元素的指针的int值? 这会令人困惑

一点也不。 假设您从一个从高到低增长的内存池中分配一个10字节的数组。 所有分配器必须做的是将该内存池的“底部”减少10,然后将该值用作分配数组的开始。 数组然后会在旧的“底部”结束。 指针运算仍然可以按预期运行,但是您会“向”低地址“增长”。

链接地址: http://www.djcxy.com/p/80245.html

上一篇: Program memory layout in linux

下一篇: square.js Maximum call stack size exceeded