realloc函数的困惑

4
我在这个参考资料中了解到C语言中的动态内存分配。
该文档提到:

realloc () 应仅用于动态分配的内存。 如果内存未动态分配,则行为是未定义的。

如果我们使用realloc(),类似于这样:
int main()
{
    int *ptr;
    int *ptr_new = (int *)realloc(ptr, sizeof(int));

    return 0;
}

根据该参考文献,这个程序是未定义的,因为指针ptr没有动态分配。但是,如果我使用类似以下的内容:
int main()
{
    int *ptr = NULL;
    int *ptr_new = (int *)realloc(ptr, sizeof(int));

    return 0;
}

根据该参考资料,这是否也属于未定义的行为?

我认为第二种情况没有引发未定义行为。我是对的吗?


你提到的文档是不完整的。请参考下面讲故事者的回答。 - Jabberwocky
1
在 C 语言中,你不应该对 realloc 的返回值进行强制类型转换,原因与 malloc 相同:https://dev59.com/dHRB5IYBdhLWcg3wgHWr - Jens Gustedt
4个回答

10
第一种情况行为未定义,第二种情况则不是。在第一种情况下,指针ptr的值是不确定的。因此,将该值传递给realloc或任何函数本身就是未定义的。
另一方面,由于当传递一个空指针值时,realloc具有良好定义的行为(类似于调用malloc1,因此第二段代码是完全合法的(除了你没有释放任何东西之外)。

1 7.22.3.5 realloc函数/p3

如果ptr是空指针,则realloc函数会为指定的大小像malloc函数一样进行分配。


1
在第一种情况下,程序几乎肯定会以“分段错误”结束,因为在堆中创建链表以查找段时不连贯,在第二种情况下,您使用NULL作为realloc的第一个参数调用,这意味着是一个等效于malloc(size)的调用。
"man realloc"说:
   void *malloc(size_t size); 
   void *realloc(void *ptr, size_t size);

如果ptr是NULL,则对于所有大小的值,该调用等效于malloc(size)。

1
唯一权威的参考资料是标准文档。n1570(最新的C11标准)有以下说明:
§7.22.3.5 realloc函数,p3:
如果ptr是空指针,则realloc函数对指定大小的空间的行为类似于malloc函数。否则,如果ptr与早先由内存管理函数返回的指针不匹配,或者空间已被调用freerealloc函数释放,则行为未定义。[...]
因此,您的第二个示例是定义良好的。

1
  1. 第一种情况显然是未定义行为,因为我们不知道 ptr 指向哪里或者在那个时刻 ptr 持有什么。而 C 标准规定 7.20.3.4.2 realloc 函数

realloc 函数释放由 ptr 指向的旧对象并返回一个指向大小由 size 指定的新对象的指针。

因此,第一种情况是未定义行为。

  1. 在第二种情况中,编译器知道 ptr 指向的内容,因此是有效的,但根据7.20.3.4.3 realloc 函数realloc()将变成malloc()

如果 ptr 是一个空指针,则 realloc 函数对于指定大小的行为类似于 malloc 函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接