int *ptr = calloc(10,(sizeof(int)));
int *ptr2 = (ptr);
for (int i = 0; i < 10; ++i) {
int r = rand() % 20000;
*(ptr + i) = r;
printf("[i:%d, v:%d, a:%p]", i, *(ptr + i), ptr+i);
fflush(stdout);
}
printf("\n");
printf("[v:%d, a:%p]", *(ptr2), ptr2);
printf("\n");
*ptr2=5;
printf("[v:%d, a:%p]", *(ptr2), ptr2);
printf("\n");
for (int i = 0; i < 10; ++i) {
printf("[i:%d, v:%d, a:%p]", i, *(ptr + i), ptr+i);
}
printf("\n");
free(ptr2);
free(ptr);
这是输出:
[i:0, v:5933, a:0x600010360][i:1, ...
[v:5933, a:0x600010360]
[v:5, a:0x600010360]
[i:0, v:5, a:0x600010360][i:1, ...
请解释为什么同一地址有两个不同的值? - 这实际上不会发生..
并且按照我的方式释放指针会产生错误:
*检测到glibc * /home/travis/build/batousik/Practical-C2/bin/.libs/lt-practical_trees:double free或corruption(fasttop):0x0000000000e05010 ***
在实际程序中,我有int数组中的测试数据和Tree数据类型。我用数组中的一些数据填充Tree,然后我试图以递归方式释放树中节点和节点的每个值,然后失败。是因为节点中的所有值指针实际上都是一个内存块吗?我应该做一些类似于从数组中记忆值到节点值新分配的内存空间的东西吗?
答案 0 :(得分:1)
因为你正在释放两次相同的指针。您指向calloc()
1 在以下行
ptr = calloc(10, sizeof(int));
然后你使ptr2
指向
ptr2 = ptr;
所以释放ptr
或ptr2
实际上是免费的同一指针。
没有任何迹象表明某个地址的值实际上有两个值,只是那个
*ptr2 = 5;
更改ptr
或ptr2
指向的第一个元素的值,实际上您在打印前始终会覆盖该地址的值。
如果您在代码中有问题的free()
来电之前执行此操作
fprintf(stderr, "value of ptr : %p\n", ptr);
fprintf(stderr, "value of ptr2: %p\n", ptr2);
将打印相同的值,因此您实际上需要一次调用free()
来传递ptr
或ptr2
中的任何一个而不是另一个calloc()
那个人通过了。
1 如果要在calloc()
调用后立即显式初始化数据,则无需使用calloc()
。此外,您应该检查malloc()
/ NULL
是否未返回{{1}}。
答案 1 :(得分:1)
int *ptr2 = (ptr);
这只是复制指针的值。在此行之后,ptr
和ptr2
都指向相同的已分配内存。然后,
free(ptr2);
free(ptr);
您正在释放相同的分配两次。
我不确定你的代码应该做什么。你有两个循环,都覆盖相同的内存块。出于某种原因,您也可以将5写入该块中的第一个int
。
答案 2 :(得分:1)
同一地址中的两个值是因为这个
*ptr2 = 5
glibc 错误是因为加倍free(ptr)
和free(ptr2)
。