更安全的重新分配方式

Safer way to realloc

我正在实现一个安全地重新分配结构的功能,以便在发生任何分配错误时不丢失信息,如下所示:

int foo (someStruct_t *ptr, int size)
{
    someStruct_t *tmp_ptr;

    tmp_ptr = realloc(ptr, size);

    if (tmp_ptr == NULL)
        return -1;

    ptr = tmp_ptr;

    return 0;
}

我的疑问在于:每次我 运行 这个函数时,我是否都没有复制为结构分配的内存?按照我的想法,我应该在退出之前释放其中一个指针,对吗?

这里主要的主要问题是,在调用 foo() 之后,在调用方中,传递给 ptr 的参数将不会更改,因为它本身是按值传递的。

您需要将指针传递给您想要重新分配的指针,以防您不想return 新指针。


也就是说,这里没有 "duplication" 内存。

  • realloc()的角度

    realloc(),如果成功,returns 指向新内存的指针并处理旧内存的取消分配工作。您无需担心任何重复或内存泄漏。

    引用 C11,章节 §7.22.3.5(强调我的

    The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. [....]

    [....] If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.

  • 从赋值来看

    ptr = tmp_ptr;这样的语句不会复制指针指向的内存或内存内容,它只是拥有同一个指针的两个副本。例如,您可以将它们中的任何一个传递给 free().

所以,归根结底,要回答问题中的 "question",

In my line of thought I should free one of the pointers before exiting, correct?

不,你不应该。您需要让新分配的指针在调用者中有用,free()-在被调用函数中使整个函数毫无意义。不过,您应该从调用者那里释放指针。

int foo (someStruct_t **ptr, int size)
{
    someStruct_t *tmp_ptr;

    tmp_ptr = realloc(*ptr, size);

    if (tmp_ptr == NULL)
        return -1;

    *ptr = tmp_ptr;

    return 0;
}

发布的代码包含几个问题:

  1. 无法在没有指针地址的情况下更改调用者指针指向的位置,因此在参数列表中使用 ** 并使用以下方式调用函数:foo( &ptr, size);
  2. 每个对调用者指针的引用现在都必须通过 *
  3. 取消引用
  4. 通常大小是指要分配的条目数房间,所以size需要乘以sizeof( someStruct_t )
  5. 请注意 size_t 用于 size 参数,因为 realloc() 期望第二个参数具有以下类型:size_t

现在建议的代码:

#include <stdlib.h>   // realloc()

int foo (someStruct_t **ptr, size_t size)
{
    someStruct_t *tmp_ptr;

    tmp_ptr = realloc( *ptr, sizeof( someStruct_t) * size );

    if (tmp_ptr == NULL)
        return -1;

    *ptr = tmp_ptr;

    return 0;
} // end function: foo