为什么堆栈地址有时会低于堆地址?

时间:2017-06-09 14:26:01

标签: c++ memory operating-system stack heap

我一直认为堆栈位于比图片2更高的堆位置。但我发现当我使用cpp(picture1)测试它时,有时堆地址会更高。我知道使用虚拟内存但我也想知道为什么堆栈和堆的虚拟地址不遵循picture2?非常感谢你!

enter image description here

enter image description here

3 个答案:

答案 0 :(得分:1)

您的图表只是概念性的。它没有反映链接,动态加载,重定位和运行时内存分配的复杂性。

答案 1 :(得分:1)

实际上,堆数据在最近的Linux系统上(可能在大多数其他桌面或服务器操作系统上)必然是连续的。 virtual address space(VAS)wikipage还有一个简化数字。

在Linux系统上,您可以试用proc(5)。尝试cat /proc/self/maps在终端上显示(当前)cat process的虚拟地址空间。另请尝试cat /proc/$$/maps(获取当前shell的VAS)和(以root身份)cat /proc/$(pidof Xorg)/maps(以获取Xorg服务器的VAS)。并尝试其他cat /proc/ some-pid /maps以获取各种流程的各种代码。

其中一个解释是,malloc有时会调用mmap(2),而不仅仅是sbrk(2)。特别是,内存块的malloc将使用mmap(我认为"阈值"使用mmap可能是malloc {1}}几兆字节)。并且库和应用程序可以使用mmap来访问某个文件。

并且mmap正在使用ASLR,所以显然不会给出连续的内存段。当然,应用程序(或free的实现)有时可以使用munmap来释放内存。而dynamic linking(请参阅ld-linux(8)& dlopen(3) ...)也使用mmapmunmap

所以虚拟地址空间可以(通常是)许多不连续的内存段组成(有时数千个)。< / p> BTW,多线程也需要几个内存段。通常每个线程都有自己的mmap - 堆栈空间。

例如,我有一些mate-terminal terminal emulator作为pid 2594的进程运行。它的进程有568个内存段(即/proc/2594/maps中的行)。通过展示所有这些,我不会破坏这个答案。我输入此答案的firefox浏览器进程在/proc/1604/maps中有1229行,以下是其中一些:

27423e6e0000-27423e720000 r-xp 00000000 00:00 0 
27423e720000-27423e730000 r-xp 00000000 00:00 0 
27423e730000-27423e760000 r-xp 00000000 00:00 0 
27423e760000-27423e780000 r-xp 00000000 00:00 0 
27423e780000-27423e7c0000 r-xp 00000000 00:00 0 
27423e7c0000-27423e7d0000 r-xp 00000000 00:00 0 
27423e7d0000-27423e7e0000 ---p 00000000 00:00 0 
27423e7e0000-27423e7f0000 r-xp 00000000 00:00 0 
7efed334d000-7efed3357000 r--p 00172000 08:01 11275829                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.23
7efed3357000-7efed3359000 rw-p 0017c000 08:01 11275829                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.23
7efed3359000-7efed335c000 rw-p 00000000 00:00 0 
7efed335c000-7efed335f000 r-xp 00000000 08:01 1704007                    /lib/x86_64-linux-gnu/libdl-2.24.so
7efed335f000-7efed355e000 ---p 00003000 08:01 1704007                    /lib/x86_64-linux-gnu/libdl-2.24.so
7efed355e000-7efed355f000 r--p 00002000 08:01 1704007                    /lib/x86_64-linux-gnu/libdl-2.24.so

因此,您的图片是粗略简化。我非常确定VAS的碎片也会发生在其他operating systems上,特别是对于像你的网络浏览器。

答案 2 :(得分:-1)

至少对于Linux和* BSD系统(可能还有其他类似unix的系统),手头的图表是正确的,而我怀疑你在Windows上运行程序显然使用了不同的内存布局。

我还强烈建议不要将代码示例粘贴为屏幕截图。只需将它们直接粘贴并缩进即可。