更安全的realloc方式

时间:2017-04-27 09:28:01

标签: c pointers memory-leaks dynamic-memory-allocation 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;
}

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

3 个答案:

答案 0 :(得分:3)

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

如果您不想return新指针,则需要将指针传递给要重新分配的指针。

那就是说,这里没有“重复”的记忆。

  • realloc()角度来看

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

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

      

    realloc函数释放ptr指向的旧对象并返回   指向size指定大小的新对象的指针。 [....]

         

    [....]如果新对象的内存不能   已分配,旧对象未被释放,其值不变。

  • 从作业角度来看

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

所以,底线,回答问题中的“问题”,

  

在我的想法中,我应该在退出之前释放其中一个指针,对吗?

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

答案 1 :(得分:1)

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;
}

答案 2 :(得分:0)

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

  1. 无法更改调用者指针指向的位置,而不指定该指针的地址,因此请在参数列表中使用**并使用以下内容调用该函数:foo( &ptr, size);
  2. 每个对来电者的提及'现在必须通过*
  3. 取消引用指针
  4. 通常大小是指要分配的数字条目空间,因此size需要乘以sizeof( someStruct_t )
  5. 请注意size_t参数的使用size,因为realloc()期望第二个参数具有类型:size_t
  6. 现在建议的代码:

    #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