动态内存分配之realloc函数的使用以及安全问题

在动态内存分配的过程中,我们经常会用到malloc,calloc等函数,在这里我们不做具体的细究。在本文中我们主要提一提realloc的使用以及需要特别注意的东西。

我们知道,在使用malloc、calloc分配内存的时候,内存大小是固定的,当我们需要调整内存大小的时候,我们该怎么办呢?这个时候,realloc就能发挥它的作用了。

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

  • ptr是要调整的内存地址
  • size 调整之后新的大小
  • 返回值为调整之后的内存起始位置

    在这里需要注意的是:
    这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。

realloc在调整内存空间时存在两种情况:
情况1:原有空间后面有足够大小的空间
情况2:原有空间后面没有足够大小的空间

情况1
当是情况1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
情况2
当是情况2 的时候,原有空间之后没有足够多的空间时,扩展的办法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。

由于上述的两种情况,realloc函数的使用就要注意一些问题。
举个例子:

#include <stdio.h>
int main()
{
int*ptr = malloc(100);
if(ptr != NULL)
{
//业务处理
}
else
{
exit(EXIT_FAILURE); 
}
//扩展容量
//代码1
ptr = realloc(ptr, 1000);//这样可以吗?(如果申请失败会如何?)
//代码2
int*p = NULL;
p = realloc(ptr, 1000);
if(p != NULL)
{
ptr = p;
}
//业务处理
free(ptr);
return 0;
}

我们考虑一下代码一会不会出现什么问题?
加入我们申请内存失败会怎么样?

如果申请内存失败,realloc会返回返回NULL。但是ptr的内存是没有被释放的。如果直接将realloc的返回值赋给ptr。那么当申请内存失败时,就会造成ptr原来指向的内存丢失,造成内存泄露。

所以为了解决这种安全问题,我们正确的做法应该是使用代码二的这种方法。

猜你喜欢

转载自blog.csdn.net/lws123253/article/details/80285962