malloc() | 堆栈和堆位置的内存地址长度差异 |C 编程



我正在学习c程序的内存管理。我得出了一个很好的疑问。(Ubuntu OS)

我的怀疑 :

我想知道堆栈内部和堆内的数据地址。但是当我尝试打印这些地址时,我观察到地址的长度不同!这里的问题是为什么它显示的堆栈地址的长度大于堆地址?

我所知道的:

  • 每个进程的堆栈内存是固定的,小于堆内存。
  • malloc() 堆上的内存分配
  • 局部变量进入堆栈

我把我的演示代码放在这里,以便您可以很好地回答我的疑问。

#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 addressn",ptr);
printf("%p:  stack addressn",&ptr);
return 0;
}

输出: 我的终端中有以下输出

0x1ea2010 : heap address
0x7ffda62cb3c0:  stack address

所以现在你可能明白我在问什么了。为什么堆栈地址的长度大于堆?堆是大内存池,所以显然它应该有更多的长度。

如果堆栈和堆分配是在同一内存块中完成的(根据现代操作系统。我在某处读过这个),所以它也应该有相同的长度。

好。请帮助我使我的记忆概念变得清晰。

注意:如果我的疑问非常简单或愚蠢,那么至少也请让我知道内存分配是如何在我的演示代码中完成的,以及不同长度的地址背后的魔力。

感谢您阅读此类帖子。 快乐回答!

鉴于您运行的是 Ubuntu,我假设您运行的是 x86 或 x86-64 平台。 假设这是真的,你的程序布局看起来像这样:

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

堆栈从高地址开始并"向下"增长(朝向递减的地址),而堆从相当低的地址开始并"向上"增长(朝向增加的地址)。%p转换说明符不会打印地址值中的前导零;如果是这样,您的地址将如下所示

0x0000000001ea2010: heap address
0x00007ffda62cb3c0: stack address

两个地址的长度确实相同,只是没有显示前导零。

printf 中的格式字符串指定跳过前导零,这是默认值。 您需要添加所需的打印地址长度,如 %016p、%016x 或 %016X(如果需要大写十六进制字符)。

正如您正确假设的那样,所有指针的长度必须相同。

您似乎正在使用 64 位地址,这意味着它们最多打印为 16 个十六进制字符。 您应该在左侧用零填充所有地址以达到 16 个字符。

0x0000000001ea2010: heap address
0x00007ffda62cb3c0: stack address

堆和堆栈都位于同一个虚拟 2^64 字节空间中。

没有标准。

但是,通常情况下,发生的情况是堆向上增长,而堆栈向下增长。因此,从逻辑上讲,在起点上,堆的大小会更小,而堆栈的大小会更大。

之所以存在这样的实现,是因为它使程序具有静态内存与动态内存重叠的机会较小。

上面有人提到了虚拟地址和物理地址。从上下文的角度来看,进程中的每一块内存都是一个虚拟地址,因此,试图解释 BUDDY 算法充其量是一种冗余,最坏的情况是无关紧要。

想象一下,你住在一条长长的街道上。 你住在街道的南端,房子的地址是1、2、3。

想象一下,这条街向北延伸一英里。 想象一下,在街道的北端,地址是998、999、1000。

想象一下,到目前为止,只开发了街道的北端和南端。 从地址20到地址990只不过是未开发的空地。

但是在街道的尽头,有很多活动。 新买家购买20至30号地块,并开始在其上建造房屋。

与此同时,在街道的北端,没有那么多活动。 看起来989和990号地块已经售出,那里正在建造一些东西。

那么,哪里有更大的未开发地块"池"呢? 在街道的北端还是南端?

到目前为止,街道南端的房屋(1-20,并且还在增长)比街道北端(990-1000)的房屋多。 到目前为止,街道南端的增长也更快。 (南端有10个地块在建,北端有2个地块。

然而,街道北端的地址(以 9 开头的 3 位数字或 4 位数字)比南端的地址(2 位数字)大。 这是什么意思? (回答:这实际上没有任何意义。

相关内容

  • 没有找到相关文章

最新更新