【问题标题】:Access to pointer passed to realloc [duplicate]访问传递给 realloc 的指针 [重复]
【发布时间】:2018-04-23 16:55:39
【问题描述】:
#include <stdio.h>
#include <stdlib.h>

main()
{
    int *p = (int *)malloc(sizeof(int));
    int *q = (int *)realloc(p,sizeof(int));
    *p = 3;
    *q = 9;
    if (p == q)
        printf("%d %d", *p, *q);

}

当我运行它时,它会在 GCC 中打印 9 9。 有人可以解释这段代码的行为吗?

【问题讨论】:

  • 你的realloc()调用不太可能改变指针p,所以调用相当于q = p
  • 你期待什么? 9 是一个有效的整数,所以它可以是结果。
  • @IharobAlAsimi 否。成功realloc() 总是使原始指针无效。
  • 在成功的realloc() 之后使用指针是未定义的行为,故事结束。
  • ..请不要要求 UB 进一步解释:(

标签: c


【解决方案1】:

标准是怎么说的?

严格遵守标准,您的程序表现出未定义的行为(C 标准,7.22.3.5):

realloc 函数释放ptr 指向的旧对象,并返回一个指向新对象 的指针,该对象具有size 指定的大小。新对象的内容应与释放前旧对象的内容相同,直至新旧大小中的较小者。新对象中超出旧对象大小的任何字节都具有不确定的值。

realloc中涉及的两个对象不一样——分配了新的,你知道它的内容和旧的一样,旧的被销毁了。您对 p 的取消引用是访问其生命周期之外的对象,这是未定义的。

在实践中(可能)会发生什么?

realloc可以在必要时移动内存区域,但不必必须移动内存区域。

在这种情况下,两个分配的大小相同 (sizeof(int))。 realloc 很可能意识到了这一点,根本不移动内存区域。

因此,p == q

PS:“可能”,因为行为未定义。您的编译器可能只是分析realloc 代码路径并注意到程序可以工作的唯一合法方式是realloc 不移动指针,而是优化为q = p。您需要调查生成的程序集才能真正找出答案。

【讨论】:

  • 调整了答案以包含 UB
  • 您可能应该提到第 4 段,Returns,它指出返回的指针可能与传递的指针具有相同的值。
  • @IharobAlAsimi 这就是我所说的“可以移动内存区域,但不是必须
  • 感谢 Treeston 的解释
猜你喜欢
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 2021-04-17
  • 1970-01-01
  • 2017-09-29
  • 2019-02-13
相关资源
最近更新 更多