为什么 malloc 分配的内存值是用 i++ 而不是 i+4 分配的(在 int 是 4 个字节大的情况下)?

Why are malloc-allocated memory values assigned with i++ instead of i+4 (in the case of an int being 4 bytes large)?

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

如果我错了请纠正我,但在 C 中,您使用 malloc 来 'reserve' / 在内存中获得 一定数量的 space 字节 .

所以int* ptr = malloc(10 * sizeof(int));分配40字节的内存/分配一个指向内存中那个区域的指针到variable/pointer ptr(假设在这台机器上int 是 4 个字节大 ).


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

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

(正确的方法 -> 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) select 每个 int 的正确地址是 4 字节大,我们甚至保留 40 字节的内存,而不是 10。也就是为什么 ptr + i (i+4) 错误?

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

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

指针算法总是根据指向对象的类型完成。也就是说,指针算法总是包含一个自动的、隐式的乘以那个大小。所以

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[],它可以并且确实占用分配的大小对象考虑在内。)

如果 p 是指向类型 T 的对象的指针,则 p+1 产生指向类型的下一个对象的地址; p++ 前进 p 指向下一个对象。

给定

char  *cp = (char *)  0x1000;
short *sp = (short *) 0x1000; // assume 2-byte short
long  *lp = (long *)  0x1000; // assume 4-byte long

则下列说法正确:

       char            short           long
       +–––+           +–––+           +–––+
0x1000 |   | <––cp     |   | <––sp     |   | <-–lp
       +–––+           + - +           + - +
0x1001 |   | <-–cp+1   |   |           |   |
       +———+           +———+           + - +
0x1002 |   | <––cp+2   |   | <––sp+1   |   |
       +———+           + - +           + - +
0x1003 |   | <––cp+3   |   |           |   |
       +–––+           +–––+           +–––+
0x1004 |   | <––cp+4   |   | <––sp+2   |   | <––lp+1
       +———+           + - +           + - +
        ...             ...             ...