realloc函数原型 : void *realloc(void *_ptr, size_t size);
realloc函数原理:当申请的空间不够我们使用时,需要扩容。
假设原空间大小为如下图所示
1.原空间已满,需要realloc申请更大的空间,若原空间后还有我们所需的足够空间则直接往后申请空间。如红色图示:
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申请的空间释放,不会导致内存泄漏。