首页 > 解决方案 > 为什么用 i++ 而不是 i+4 分配 malloc 分配的内存值(在 int 为 4 字节大的情况下)?

问题描述

我的头脑现在很困惑和震惊,希望有人能帮助我解开它/让我再次走上正确的道路。

如果我错了,请纠正我,但在 C 中,您使用 malloc 来“保留”/在内存中获得一定数量的空间(以字节为单位)。

因此int* ptr = malloc(10 * sizeof(int));分配 40 字节的内存/将指向内存中该区域的指针分配给变量/指针 ptr(假设在这台机器上一个int 是 4 字节大)。


我不明白的是,当您为数组分配值时,为什么 i 是 i++(1 个增量)而不是 i + 4 (即 int 的大小)。这是有道理的,因为我们有一个 40 字节的内存块并且我们迭代 10 次 à +4 字节 => 40 字节。

代码示例: 为了简单起见,假设函数 random() 返回一个随机整数。

(正确的方法-> 10 个随机整数):

for(int i = 0; i < 10; i++) {
    *(ptr + i) = random();
}

(我对 i+4 字节的想法,产生了奇怪的结果,错误的方式):

for(int i = 0; i < 10; i+=4) {
    *(ptr + i) = random();
}

我的问题是,为什么 ptr + i (i+1) 选择每个 int 的正确地址时 int 是 4 字节大,我们甚至保留 40 字节的内存,而不是 10.aka 为什么是 ptr + i (i+4 ) 错误的?

(在我看来,迭代 i+4 而不是 1 是有意义的。通过 malloc => 0x400 分配的 start/ptr,int 有 4 个字节大,因此下一个地址/下一个 int 位于 0x404、0x408 等......不是0x401, 0x402 ....)

标签: c++cpointersmemorymemory-address

解决方案


指针算法和内存分配是两个不同的东西。

指针算术始终基于指向对象的类型。也就是说,指针算术总是包含该大小的自动、隐式乘法。所以

int *p;
/* ... */
p++;

总是以字节为单位增加p地址sizeof(int)

它必须是这种方式,因为除其他外,指针算法模拟数组访问。所以它必须考虑到指向对象的大小,以便像这样的符号

*(p + 1)

p[1]

正常工作。

malloc另一方面,该函数始终以字节为单位。一个原因——也许原因——恰恰malloc是一个函数。当你说类似

malloc(10 * sizeof(int))

malloc你机器上的函数 接收到的数字只有 40。malloc无法知道是 40 个大小为 1 的东西,还是 10 个大小为 4 的东西,还是一个大小为 40 的东西。它只知道它必须分配 40 个字节. (还有与对齐有关的要求。)

如果您希望它以不同的方式工作-如果您想要类似的东西

int *ip = malloc(10);

自动缩放sizeof(int)——很难看出它在 C 中是如何工作的。(相比之下,在 C++ 中有new[],它可以并且确实考虑了分配对象的大小。)


推荐阅读