gpt4 book ai didi

c - 在数组外部写入然后使用 realloc 后出现错误的数组值

转载 作者:行者123 更新时间:2023-11-30 18:27:06 25 4
gpt4 key购买 nike

第一个循环的输出是 1..20。第二个循环的输出是 1..30。然后第三个循环从 1..9 开始正常,然后由于某种原因它在第十个值处输出 81。

奇怪的是,如果我为第三个循环重新分配 11 个元素并打印 11 个值,那么它会打印 1..11 就好。

我错过了什么?

#include <stdio.h>

int main() {
unsigned int *P;
P = malloc(20 * sizeof(int));

for (int i = 0; i < 20; i ++) {
(*(P + (i+1))) = (i+1);
printf("(%d) Pointer address: %x | Pointer value %d \n", (i+1), (P + (i+1)), *(P + (i+1)));
};

P = realloc(P, 30 * sizeof(int));
printf("------------------------------------------------------------ \n");
printf("After reallocation... \n");
printf("------------------------------------------------------------ \n");

for (int i = 0; i < 30; i ++) {
if (i > 19)
(*(P + (i+1))) = (i+1);
printf("(%d) Pointer address: %x | Pointer value %d \n", (i+1), (P + (i+1)), *(P + (i+1)));
};


P = realloc(P, 10 * sizeof(int));
printf("------------------------------------------------------------ \n");
printf("After deallocation... \n");
printf("------------------------------------------------------------ \n");

for (int i = 0; i < 10; i ++)
printf("(%d) Pointer address: %x | Pointer value %d \n", (i+1), (P + (i+1)), *(P + (i+1)));
return 0;
}

最佳答案

数组索引从 0 开始,而不是从 1 开始。因此可以使用 *(P + 19) 访问数组的最后一个元素。当i = 19在你的第一个循环中,(*(P + (i+1))) = (i+1);写入*(P + 20)这是越界的。越界访问内存是未定义的行为。

删除所有 +1从代码中的数组访问使其正常运行,即。全部更改P + (i+1)到只是P + i 。大多数程序员也非常喜欢 P[i]而不是*(P + i)为了可读性。另外一些程序员更喜欢写 &P[i]代替P + i - i的地址第一个元素。

另外打印一个指针值 %x是未定义的行为。 %xprintf需要其参数为 unsigned int 。路过unsigned int*它的值是未定义的行为,它恰好在您的计算机上工作,因为最有可能的大小为 unsigned intunsigned int * 的大小相同。打印指针值的常见方法是使用 %p printf说明符并将指针强制转换为 void* 。 (请注意,在大多数体系结构上,实际上并不需要强制转换为 void*,因为所有指针都具有相同的大小,但不这样做在技术上是未定义的行为。)如果您仍想使用 %x ,您应该将参数转换为正确的类型,例如 (unsigned)(uintptr_t)(P + i) .

此外,您没有包含 #include <stdlib.h>对于 mallocrealloc功能。您至少应该看到编译器发出的有关隐式声明的警告。这也是未定义的行为,因为隐式声明的函数与实际定义不匹配。隐式声明返回 int ,而mallocrealloc返回 void* .

记住错误处理。每个reallocmalloc可以返回 NULL万一它无法分配内存。

修正这些错误后:

#include <stdio.h>
#include <stdlib.h>

int main() {
unsigned int *P;
P = malloc(20 * sizeof(unsigned int));

for (int i = 0; i < 20; i++) {
P[i] = i + 1;
printf("(%d) Pointer address: %p | Pointer value %d \n",
i + 1, (void*)(P + i), P[i]);
};

P = realloc(P, 30 * sizeof(unsigned int));
printf("------------------------------------------------------------ \n");
printf("After reallocation... \n");
printf("------------------------------------------------------------ \n");

for (int i = 0; i < 30; i ++) {
if (i > 19) {
P[i] = i + 1;
}
printf("(%d) Pointer address: %p | Pointer value %d \n",
i + 1, (void*)(P + i), P[i]);
};


P = realloc(P, 10 * sizeof(unsigned int));
printf("------------------------------------------------------------ \n");
printf("After deallocation... \n");
printf("------------------------------------------------------------ \n");

for (int i = 0; i < 10; i ++)
printf("(%d) Pointer address: %p | Pointer value %d \n",
i + 1, (void*)(P + i), P[i]);
return 0;
}

输出on godbolt :

(1) Pointer address: 0x13c4260 | Pointer value 1 
(2) Pointer address: 0x13c4264 | Pointer value 2
(3) Pointer address: 0x13c4268 | Pointer value 3
(4) Pointer address: 0x13c426c | Pointer value 4
(5) Pointer address: 0x13c4270 | Pointer value 5
(6) Pointer address: 0x13c4274 | Pointer value 6
(7) Pointer address: 0x13c4278 | Pointer value 7
(8) Pointer address: 0x13c427c | Pointer value 8
(9) Pointer address: 0x13c4280 | Pointer value 9
(10) Pointer address: 0x13c4284 | Pointer value 10
(11) Pointer address: 0x13c4288 | Pointer value 11
(12) Pointer address: 0x13c428c | Pointer value 12
(13) Pointer address: 0x13c4290 | Pointer value 13
(14) Pointer address: 0x13c4294 | Pointer value 14
(15) Pointer address: 0x13c4298 | Pointer value 15
(16) Pointer address: 0x13c429c | Pointer value 16
(17) Pointer address: 0x13c42a0 | Pointer value 17
(18) Pointer address: 0x13c42a4 | Pointer value 18
(19) Pointer address: 0x13c42a8 | Pointer value 19
(20) Pointer address: 0x13c42ac | Pointer value 20
------------------------------------------------------------
After reallocation...
------------------------------------------------------------
(1) Pointer address: 0x13c52d0 | Pointer value 1
(2) Pointer address: 0x13c52d4 | Pointer value 2
(3) Pointer address: 0x13c52d8 | Pointer value 3
(4) Pointer address: 0x13c52dc | Pointer value 4
(5) Pointer address: 0x13c52e0 | Pointer value 5
(6) Pointer address: 0x13c52e4 | Pointer value 6
(7) Pointer address: 0x13c52e8 | Pointer value 7
(8) Pointer address: 0x13c52ec | Pointer value 8
(9) Pointer address: 0x13c52f0 | Pointer value 9
(10) Pointer address: 0x13c52f4 | Pointer value 10
(11) Pointer address: 0x13c52f8 | Pointer value 11
(12) Pointer address: 0x13c52fc | Pointer value 12
(13) Pointer address: 0x13c5300 | Pointer value 13
(14) Pointer address: 0x13c5304 | Pointer value 14
(15) Pointer address: 0x13c5308 | Pointer value 15
(16) Pointer address: 0x13c530c | Pointer value 16
(17) Pointer address: 0x13c5310 | Pointer value 17
(18) Pointer address: 0x13c5314 | Pointer value 18
(19) Pointer address: 0x13c5318 | Pointer value 19
(20) Pointer address: 0x13c531c | Pointer value 20
(21) Pointer address: 0x13c5320 | Pointer value 21
(22) Pointer address: 0x13c5324 | Pointer value 22
(23) Pointer address: 0x13c5328 | Pointer value 23
(24) Pointer address: 0x13c532c | Pointer value 24
(25) Pointer address: 0x13c5330 | Pointer value 25
(26) Pointer address: 0x13c5334 | Pointer value 26
(27) Pointer address: 0x13c5338 | Pointer value 27
(28) Pointer address: 0x13c533c | Pointer value 28
(29) Pointer address: 0x13c5340 | Pointer value 29
(30) Pointer address: 0x13c5344 | Pointer value 30
------------------------------------------------------------
After deallocation...
------------------------------------------------------------
(1) Pointer address: 0x13c52d0 | Pointer value 1
(2) Pointer address: 0x13c52d4 | Pointer value 2
(3) Pointer address: 0x13c52d8 | Pointer value 3
(4) Pointer address: 0x13c52dc | Pointer value 4
(5) Pointer address: 0x13c52e0 | Pointer value 5
(6) Pointer address: 0x13c52e4 | Pointer value 6
(7) Pointer address: 0x13c52e8 | Pointer value 7
(8) Pointer address: 0x13c52ec | Pointer value 8
(9) Pointer address: 0x13c52f0 | Pointer value 9
(10) Pointer address: 0x13c52f4 | Pointer value 10

关于c - 在数组外部写入然后使用 realloc 后出现错误的数组值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59620872/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com