C中的指针混淆

p4rjhz4m  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(113)
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a = 4;
    int *p = malloc(sizeof(int) * a);
    int *g = malloc(sizeof(int) * a);
    p += 8;
    printf("%p\n", p);
    printf("%p\n", g);
    
}

字符串
我已经运行这个程序好几次了,每次打印出来的p和g的值都是一样的。我不太确定为什么会发生这种情况--理论上malloc不能在内存中选择p和g指向的任何地方吗?为什么p + 8总是等于g?任何澄清都是非常感激的。
谢谢你,谢谢

qfe3c7zg

qfe3c7zg1#

这个程序我已经运行过好几次了,每次最后打印出来的p和g的值都是一样的
这是因为你的内存是如何分配的。
第一个malloc为4个整数分配内存。假设它们每个是4个字节,那么就是16个字节。

0              1              2              3 
0123456789abdef0123456789abdef0123456789abdef0123456789abdef
^--------------
p

字符串
第二个malloc为另外4个整数分配内存。这个内存可以分配在任何空闲槽中,但它碰巧是这样的。

0              1              2              3 
0123456789abdef0123456789abdef0123456789abdef0123456789abdef
^--------------               ^--------------
p                             g


如果你给p加上8,它会移动8个整数,32个字节,也就是g
差距中的内存是什么?谁知道呢。内存可以在malloc认为合适的情况下分配。
然而,* 不能保证 * 内存会以这种方式分配。在我的系统上,p += 4工作,这意味着没有间隙。

x33g5p2x

x33g5p2x2#

这就是malloc()的工作原理

mallocheap上以所谓的chunk形式保留内存,可以是可变大小(固定大小的header +可变大小的数据)。可以分配的最小数据量为16字节。
最小分配大小:4字节ptrs:16字节(包括开销)8字节ptrs:32字节(包括开销)
虽然分配了4 * sizeof(int)的数据,但malloc使用“块”,其中包含用于簿记的额外元数据,这在free内存时是需要的。
每个分配块的最小开销:4或8字节(如果4字节大小)8或16字节(如果8字节大小)每个错误块都有一个隐藏的开销字,用于保存大小和状态信息,以及额外的交叉检查字
malloc希望避免空闲内存的分段。因此,malloc将两个块相邻放置以防止内存泄漏是合乎逻辑的,并且将它们放在一起是有意义的,因为这是最有效的方法。
如果我们假设int的大小是4个字节,你必须将第一个指针增加8 * sizeof(int)或32个字节,以指向下一个分配的数据:

p + header size(16 bytes) + data size(16 bytes) = b
p + 32 = b

字符串
下面是两个相邻的malloc块的图像:


的数据

uinbv5nw

uinbv5nw3#

为什么p + 8总是等于g?
这是一个错误的问题。在你的特定系统中,在你的特定程序中,它们总是相等的。
除非你有理由相信这是不可能的或明确禁止的,否则为什么会令人惊讶呢?
从理论上讲,malloc不能在内存中选择p和g指向的任何地方吗?
好吧,任何地方都可以免费商店。但这并不意味着它是随机的-这只是额外的工作没有好处。

相关问题