动态内存管理中内存泄露问题
- malloc()为动态内存分配函数,可以申请一块连续的内存空间,可以根据需要指定申请内存的大小,申请的单位为字节。
注意:
1.若申请内存空间较大时,就会申请失败,返回空指针。所以申请后一定要判定指针是否为空。
2,使用malloc()申请的内存,必须进行释放,否则会出现“内存泄露”的问题。
内存泄露:当在程序中反复使用molloc函数申请内存空间,但并没有使用free函数来进行空间释放,系统内存越来越少,最终导致内存不足。
会导致内存泄露的几种情况:
1.程序执行不到free()就跳出
void Fun()
{
int *p = (int*)malloc(sizeof(int)* 10);
if (p == NULL)
{
return;
}
if (cond1)
{
return;
}
if (cond2)
{
return;
}
do_something;
free(p);
}
在上述程序中,一旦程序中满足了cond1、cond2等条件,就会return跳出,并不能执行到free()。导致申请的空间内存不能被释放,从而可能出现内存泄露问题。
2、重复申请
void Fun()
{
int *p = (int*)malloc(sizeof(int)* 10);
p = (int *)malloc(sizeof(int)* 10);
if (p == NULL)
{
return;
}
free(p);
}
在对空间的重复申请时,并没有对第一个p进行空间释放,导致第一个p中的内存被浪费。
3、函数的嵌套
void Fun3()
{
malloc();
}
void Fun2()
{
Fun3;
}
void Fun()
{
Fun2();
}
int main()
{
Fun();
return 0;
}
在函数嵌套中,若对空间内存申请的函数处于整个程序的角落里,并且嵌套调用,并没有对其空间进行释放,会导致内存泄露,并且不易找到。
4、反复给一个容器中添加元素
void Fun()
{
std::vecter<int> v;
while (1)
{
v.push_back(10);
}
}
代码中虽然没有malloc,但反复给一个容器中添加元素,而不清理,同样导致内存不足,等同于内存泄露。
所以在使用malloc()函数申请内存时,一定要对齐进行内存释放。
calloc ()和malloc()函数的区别:
- calloc()申请的内存空间全被初始化为0;
- malloc() 申请的内存空间并没有初始化。
如果申请的内存空间需要初始化为其他值时,calloc()函数相当于多余了一部操作,会影响程序性能。
realloc ()和malloc()函数的比较:
- 可控性较低
realloc()函数的功能是把一个动态申请到的内存空间进行扩容。
但若出现已申请的内存空间后面不足以放下扩容的空间,这时,realloc()会自动在内存中找处一段连续的空间,并把原来的内存中的数据拷贝过去,并释放原来的空间。
这种情况为触发扩容,会导致大规模的拷贝内存,操作低效。