使用realloc函数容易出现的陷阱(内存泄露)

realloc函数原型 : void *realloc(void *_ptr, size_t size);

realloc函数原理:当申请的空间不够我们使用时,需要扩容。

假设原空间大小为如下图所示

使用realloc函数容易出现的陷阱(内存泄露)_第1张图片

1.原空间已满,需要realloc申请更大的空间,若原空间后还有我们所需的足够空间则直接往后申请空间。如红色图示:

使用realloc函数容易出现的陷阱(内存泄露)_第2张图片

2.原空间已满,需要realloc申请更大的空间,若原空间后没有我们所需的足够空间,则需要另外开辟黑色空间加上红色空间大小的内存。并且将原黑色空间里的数据复制到新申请空间中,把原黑色空间内存释放掉。

3.原空间后没有足够空间,并且其他区域也无法申请空间,这时就会导致申请失败。

int main()
{
    int* ptr = (int*)malloc(sizeof(int) * 10);//1
    assert(ptr != NULL);
    if (ptr == NULL)
        return 1;
    for (int i = 0;i < 10;i++)
    {
        ptr[i] = i;
    }                                         //2
    int* ptr = (int*)realloc(ptr, sizeof(int) * 20);//3
    assert(ptr != NULL);
    if (ptr == NULL)
     { 
        return 1;
    for (int i = 10;i < 20;i++)
    {
        ptr[i] = i;                            //4
    }
    free(ptr);
    return 0;
}

上面代码中1处我们申请了10个字节大小的空间,2处将1-9分别赋值给数组,3处扩容了十个字节大小的空间,4处将10-19赋值给数组。

但是需要注意的是:在3处当我们realloc申请空间失败的时候,将返回NULL,此时我们将空指针赋值给了ptr,但是在1处申请的空间没有指针指向,所以那段空间无法被free释放,此时便会造成内存泄漏。

修改如下:

int main()
{
    int* ptr = (int*)malloc(sizeof(int) * 10);//1
    assert(ptr != NULL);
    if (ptr == NULL)
        return 1;
    for (int i = 0;i < 10;i++)
    {
        ptr[i] = i;
    }                                         //2
    int* p = (int*)realloc(ptr, sizeof(int) * 20);//3
    
    assert(p != NULL);
    if (p == NULL)
     {
       free(ptr);                              //6
       return 1;
     }
     ptr=p;                                       //5
    for (int i = 10;i < 20;i++)
    {
        ptr[i] = i;                            //4
    }
    free(ptr);
    return 0;
}

这样在6处我们借助中间变量存取realloc申请空间返回的地址,即使realloc申请失败也可以将原来malloc申请的空间释放,不会导致内存泄漏。

你可能感兴趣的:(#C语言,c++,c语言)