【问题标题】:C same address with different pointers?C具有不同指针的相同地址?
【发布时间】:2015-03-07 21:54:01
【问题描述】:
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 or corruption (fasttop): 0x0000000000e05010 ***

在实际程序中,我在 int 数组和 Tree 数据类型中有测试数据。我用数组中的一些数据填充树,然后我试图递归地释放树中节点和节点的每个值,但失败了。是不是因为节点中的所有值指针实际上都是一个内存块?然后我应该将数组中的值 memcopy 到新分配的节点值的内存空间中吗?

【问题讨论】:

  • 该值不同,因为您每次打印前都明确更改它。
  • @inspired我很抱歉这个问题用 c 熬夜了,inded 代码每次都会改变值

标签: c arrays pointers int dereference


【解决方案1】:
  1. 因为你要释放同一个指针两次。你在下面一行中指向calloc()1返回的地址

    ptr = calloc(10, sizeof(int));
    

    然后你让ptr2指向同一个地方

    ptr2 = ptr;
    

    所以释放ptrptr2 实际上释放的是同一个指针。

  2. 没有任何迹象表明给定地址的值实际上有两个值,只是

    *ptr2 = 5;
    

    更改ptrptr2 指向的第一个元素的值,实际上您总是在打印之前覆盖该地址处的值。

如果您在代码中有问题的 free() 调用之前执行此操作

fprintf(stderr, "value of ptr : %p\n", ptr);
fprintf(stderr, "value of ptr2: %p\n", ptr2);

将打印相同的值,因此您实际上需要一次调用free() 传递ptrptr2 中的任何一个,但在传递一个传递后不需要传递另一个。


1如果要在调用calloc() 之后立即显式初始化数据,则不需要使用calloc()。此外,您应该检查calloc()/malloc() 没有返回NULL

【讨论】:

  • 同一个地址有两个不同的值呢?
  • @Batousik 我在你的输出中根本看不到这种情况。
  • "...就在 free() 调用之前..." - 这本身就是一个问题,因为它们都拥有相同的地址。应该有一个调用free()
  • @iharob 我很抱歉这个问题用 c 熬夜了,inded 代码每次都会改变值
  • 在实际程序中,我有 int 数组中的测试数据和 Tree 数据类型。我用数组中的一些数据填充树,然后我试图递归地释放树中节点和节点的每个值,但失败了。是不是因为节点中的所有值指针实际上都是一个内存块?然后我应该将数组中的值 memcopy 到新分配的内存空间中吗? @iharob
【解决方案2】:
int *ptr2 = (ptr);

这只是复制指针的。在这一行之后,ptrptr2 都指向同一个分配的内存。那么,

free(ptr2);
free(ptr);

您正在释放相同的分配两次

我不太确定您的代码应该做什么。您有两个循环都覆盖同一块内存。出于某种原因,您也在向该块中的第一个 int 写入 5。

【讨论】:

  • 同一个地址有两个不同的值呢?
  • 因为你在第一个循环中写入数据,打印它,然后在那里写一个 5,打印它,然后你的第二个循环覆盖它。同样,ptrptr2 指向 same 内存。在你使用ptr2的任何地方,你不妨将其替换为ptr
  • 好吧,我问错了,对不起,我已经编辑了问题@Jonathon
【解决方案3】:

同一个地址的两个值是因为这个

*ptr2 = 5

glibc 错误是由于 free(ptr)free(ptr2) 重复造成的。

【讨论】:

  • 第一个问题是“为什么同一个地址有两个不同的值”。
  • 我的错。没有错,但您要解决的问题模棱两可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-04
  • 1970-01-01
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多