为什么 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
+———+ + - + + - +
... ... ...
我现在很困惑和震惊,希望有人能帮我解惑/让我再次走上正确的道路。
如果我错了请纠正我,但在 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
+———+ + - + + - +
... ... ...