简体   繁体   English

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

[英]malloc() | difference in memory address length of stack and heap locations | C programming

I am learning memory management of c program. 我正在学习c程序的内存管理。 I have arrived at a good doubt. 我已经很好地怀疑了。 (Ubuntu OS) (Ubuntu操作系统)

My Doubt : 我的怀疑:

I wanted to know addresses of data that lie inside stack and inside heap both . 我想知道位于堆栈内部和堆栈内部数据的地址。 But when I tried printing those addresses, I observed that length of addresses are different! 但是当我尝试打印那些地址时,我发现地址的长度不同! Question here is why it is displaying stack address having more length than heap address? 这里的问题是为什么它显示的堆栈地址比堆地址长?

What I know : 我知道的 :

  • Stack memory per process is fixed and less than heap memory. 每个进程的堆栈内存是固定的,小于堆内存。
  • malloc() memory allocate on heap malloc()内存在堆上分配
  • local variable goes on stack 局部变量进入堆栈

I put my demo code here so that you can answer my doubt well. 我将演示代码放在这里,以便您可以很好地回答我的疑问。

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

}

Output : I got following output in my terminal 输出:我在终端中得到以下输出

0x1ea2010 : heap address
0x7ffda62cb3c0:  stack address

So now you might understand what I am asking. 所以现在您可能已经明白我的要求了。 Why stack address has more length than heap? 为什么堆栈地址比堆长? Heap is large pool of memory so obviously it should have more length. 堆是很大的内存池,因此显然它应该有更多的长度。

If stack and heap allocation is done in same memory block(as per modern OS..I have read this somewhere) so then also it should have same length. 如果堆栈和堆分配是在相同的内存块中完成的(按照现代OS ..我已经在某处阅读过),那么它的长度也应相同。

Okay. 好的。 Please help me to make my memory concepts crystal clear. 请帮助我使我的记忆概念更加清晰。

Note : If my doubt is very simple or silly then also at least please let me know how memory allocation is done in my demo code and magic behind different lengths of addresses. 注意:如果我的疑问很简单或很愚蠢,那么至少也请让我知道如何在我的演示代码中完成内存分配,以及如何在不同长度的地址后面添加魔术。

Thanks for reading such post. 感谢您阅读此类文章。 Happy answering ! 回答愉快!

Given that you are running Ubuntu, I'm assuming you're running on an x86 or x86-64 platform. 考虑到您正在运行Ubuntu,我假设您正在x86或x86-64平台上运行。 Assuming that's true, your program layout looks something like this: 假设是这样,您的程序布局如下所示:

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

The stack starts at a high address and grows "downwards" (towards decreasing addresses), while the heap starts at a fairly low address and grows "upwards" (towards increasing addresses). 堆栈从高位地址开始,然后“向下”增长(向减少的地址),而堆从低位地址开始,然后向“向上”增长(向增加的地址)。 The %p conversion specifier isn't printing the leading zeros in the address values; %p转换说明符不会在地址值中打印前导零; if it did, your addresses would look like 如果是这样,您的地址看起来像

0x0000000001ea2010: heap address
0x00007ffda62cb3c0: stack address

Both addresses really are the same length, it's just that the leading zeros aren't being displayed. 两个地址的长度实际上相同,只是没有显示前导零。

It seems like you are working with 64bit addresses, meaning that they print out as up to 16 hexadecimal characters. 似乎您正在使用64位地址,这意味着它们最多可以打印出16个十六进制字符。 you should pad all addresses with zeros on the left hand side to reach 16 characters. 您应该在左侧用零填充所有地址,以达到16个字符。

0x0000000001ea2010: heap address
0x00007ffda62cb3c0: stack address

The heap and stack(s) both live in the same virtual 2^64 byte space. 堆和堆栈都生活在相同的虚拟2 ^ 64字节空间中。

Your format string in printf specifies to skip leading zeroes, that's the default. 您在printf中的格式字符串指定跳过前导零,这是默认值。 You need to add the desired length of your printed addresses as in %016p, %016x or %016X (if you want uppercase hexadecimal characters). 您需要添加所需的打印地址长度,如%016p,%016x或%016X(如果需要大写十六进制字符)。

As you correctly assume, all pointers must be the same length. 正确假设,所有指针的长度必须相同。

There is no standard. 没有标准。

But, typically, what happens is Heaps grows upwards while Stacks grows downward. 但是,通常情况下,堆会向上增长,而堆栈会向下增长。 Hence, logically, at starting point, Heap will be smaller in size , while, Stack is larger in size. 因此,从逻辑上讲,在开始时,堆的大小将较小,而堆栈的大小将较大。

The reason why such an implementation is present is because, it gives a program a lesser chance to have overlap of static vs dynamic memory. 存在这种实现的原因是,它给程序提供了较少的机会使静态内存与动态内存重叠。

Someone above mentioned Virtual addresses and Physical addresses. 上面有人提到了虚拟地址和物理地址。 Contextually speaking, every piece of memory in a process is a Virtual address, hence, trying to explain the BUDDY algorithm is aa redundancy at best and irrelevant at worst. 从上下文上讲,进程中的每个内存都是虚拟地址,因此,试图解释BUDDY算法充其量是一种冗余,而在最坏的情况下则无关紧要。

Imagine you live on a long street. 想象一下你住在一条漫长的街道上。 You live at the south end of the street, where the house addresses are 1, 2, 3. 您住在街道的南端,房屋地址是1、2、3。

Imagine that the street runs north for one mile. 想象一下,这条街向北延伸一英里。 Imagine that at the north end of the street, the addresses are 998, 999, 1000. 想象一下,在这条街的北端,地址是998、999、1000。

Imagine that so far, only the north and south ends of the street have been developed. 想象到现在为止,只有这条街的南北两端都已开发。 From address 20 to address 990 is nothing but undeveloped vacant lots. 从地址20到地址990只是未开发的空地。

But at your end of the street there's lots of activity. 但是在这条街的尽头有很多活动。 New buyers buy lots 20 through 30 and start building houses on them. 新买家购买20至30地段,并开始在其上建造房屋。

Meanwhile, at the north end of the street, there's not so much activity. 同时,在这条街的北端,活动很少。 It looks like lots 989 and 990 have been sold, and something's being built there. 看来已经售出了989和990号拍品,并且在那里正在建造物品。

So, where is there a bigger "pool" of undeveloped lots? 那么,哪里有更大的未开发土地“池”? At the north or the south end of the street? 在这条街的北端还是南端?

So far, there are more houses at the south end of the street (1-20, and growing) than there are at the north end of the street (990-1000). 到目前为止,这条街的南端(1-20处,并且正在增长)的房屋数量比这条街的北端(990-1000)的房屋更多。 So far, growth is faster at the south end of the street, also. 到目前为止,街道南端的增长速度也更快。 (10 lots under construction at the south end, versus 2 at the north.) (南端在建10个地块,北端在建2个地块。)

And yet, the addresses at the north end of the street are bigger (3 digits starting with 9, or 4 digits) than they are at the south (2 digits). 但是,这条街北端的地址比南端的地址(2位数字)大(以9或4位数字开头的3位数字)。 What does this mean? 这是什么意思? (Answer: it doesn't really mean anything.) (答案:这实际上没有任何意义。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM