【问题标题】:What's the bug with a possible wrapper function of realloc C function?realloc C 函数的可能包装函数有什么错误?
【发布时间】:2015-01-28 16:32:22
【问题描述】:

我想知道 realloc C 函数的以下可能的包装函数中可能存在的错误:

void reallocX(void** ptr, size_t size)
{
    void *new_ptr = realloc(*ptr, size);
    if (new_ptr != NULL)
    {
        if (new_ptr != *ptr)
        {
            *ptr = new_ptr;
        }
    }
    else
    {
        printf( "Help! realloc returned NULL!\n");
        exit( EXIT_FAILURE);
    }
}

.

我知道它是基于malloc C函数可能的包装函数,即:

void *
mallocX (size_t nbytes)
{
  void *ptr;
  ptr = malloc (nbytes);
  if (ptr == NULL) {
    printf( "Help! malloc returned NULL!\n");
    exit (EXIT_FAILURE);
  }
  return ptr;
}

。此 malloc C 函数包装函数基于 this webpage 的“mallocc”C 函数。

感谢您的帮助。

【问题讨论】:

  • 它有一个错误是因为?
  • 看来是别人多想知道。
  • @iharob 它确实有一个错误。请参阅下面的答案。

标签: c++ c malloc realloc


【解决方案1】:

来自realloc 的空指针返回值可能表示:

  1. 该函数未分配存储空间。
  2. size 参数为零并且内存已被释放。

您的代码涵盖了第一种可能性,但没有涵盖第二种可能性。空返回值可以是有效的,表示内存块的释放成功完成。在这些情况下发出错误信号是一个错误。

注意这适用于 C90 C++98

如 cmets 中所述,传递 0 的大小参数是 C99/C11 C++11 中的特定实现。

【讨论】:

  • 我会考虑将 0 的大小传递给 realloc 作为一个错误开始。关于如何处理这种情况,不同的实现通常以不一致的方式发生变化。 realloc 到大小为 0 not 指定为与​​ free 相同,除非在 malloc(0) 返回空指针的实现中,但某些实现错误地使其相同,并且没有干净的方法处理差异(以确定它是错误还是预期的行为)。只是避免这样做。
  • realloc的定义。
  • @R.. 感谢您指出这一点。我添加了有关不同标准的注释。
【解决方案2】:

至少有一个错误;这一行:

    if (new_ptr != *ptr)

调用未定义的行为。在realloc 成功后,任何旧指针的使用,尤其是与新指针的比较,都是被禁止的。您需要无条件地进行分配。

此外,虽然这不是内部错误,但外部 API 设计错误且容易出错。调用者指针的类型通常不是void *,而是其他一些指针类型,如char *struct foo *,你会让用户这样做:

reallocX((void **)&myptr, size);

这会导致您的函数通过别名违规调用未定义的行为(至少;如果不同的指针类型在大小/表示上有所不同,也可能是越界写入),因为它正在访问位于以下地址的 void * 对象不指向void * 对象,而是指向其他类型的指针对象。

这些类型的包装是有害的,需要被拒绝。没有办法正确/安全地完成它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 2020-08-18
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 2021-06-09
    • 2013-09-19
    相关资源
    最近更新 更多