C++ - 内存泄漏如何避免

内存知识:

C语言(计算机专业应该知道的内存知识)_学习&笔记的博客-CSDN博客

​​​​​​C语言(计算机专业应该知道的管理内存的数据结构)_学习&笔记的博客-CSDN博客_操作系统实现内存管理常用的数据结构

C语言为内存分配空间(代码段、数据段、bss段、存储类、变量的生命周期)_学习&笔记的博客-CSDN博客_内存代码段和数据段

1.内存溢出与内存泄漏

内存溢出:内存溢出 OOM (out of memory),是指程序在申请内存时,没有足够的内存空间供

其使用,出现out of memory;比如申请了一个int,但给它存了long才能存下的数,那就是内存溢

出。

内存泄漏:对于C++的内存泄漏,总结一句话:就是new出来的内存没有通过delete合理的释放

掉!

2.内存泄漏出现的情况总结

NO1: 程序循环new创建出来的对象没有及时的delete掉,导致了内存的泄露。

#include <iostream>
#include <new.h>

using namespace std;

void out_of_memroy()
{
    cout << "ERROR:内存已耗尽!" << endl;
}

int main()
{
    set_new_handler(out_of_memroy);//注意参数传递的是函数的地址;
    while(1)
    {
        new int[1000];
    }
    return 0;
}

以上代码会在堆区疯狂的动态分配内存空间,导致系统内存耗尽时自动调用set_new_handler参数列表中的函数,打印出ERROR:内存已耗尽!

NO2: 指针重新赋值导致内存泄漏

char * p = (char *)malloc(10);
char * np = (char *)malloc(10);

其中,指针变量 p 和 np 分别被分配了 10 个字节的内存。

在这里插入图片描述

p=np;

这时候,指针变量 p 被 np 指针重新赋值,其结果是 p 以前所指向的内存位置变成了孤立的内存。

它无法释放,因为没有指向该位置的引用,从而导致 10 字节的内存泄漏。

在这里插入图片描述

 NO3: 错误的内存释放导致内存泄漏

假设有一个指针变量 p,它指向一个 10 字节的内存位置。该内存位置的第三个字节又指向某个动

态分配的 10 字节的内存位置。

在这里插入图片描述

free(p);

很显然,如果通过调用 free 来释放指针 p,则 np 指针也会因此而变得无效。np 以前所指向的内

存位置也无法释放,因为已经没有指向该位置的指针。换句话说,np 所指向的内存位置变为孤立

的,从而导致内存泄漏。

改正:

free(p->np);
free(p);

NO4: new创建了一组对象数组,内存回收的时候却只调用了delete而非delete []来处理导致内存泄

漏。

class Object1
{
    int a;
    int b;
};

int main() {
Object1* arry1 = new Object1[100];//创建包含100个Object1的对象数组arry1并返回数组首地址;
Object1* arry2 = new Object1[100];//创建包含100个Object1的对象数组arry2并返回数组首地址;
delete []arry1;//回收了数组arry1里的所有对象动态创建时占用的内存空间;
delete  arry2;//回收了数组arry2里的第一个对象动态创建时占用的内存空间,导致其他99个对象的内存空间泄露;

cout << "Press any key to continue... ..." << endl;
getchar();
return 0;
}

 NO5:双指针释放错误,存在指针释放的遗漏。

如例子正确的释放一个双指针。

Void FunRightA()
{
	Char **p = new char*[10];
	For(int i=0;i<10;i++)
	{
		p[i] = new char[10];
	}
	If(p!=nullptr)
	{
		For(int i=0;i<10;i++)
		{	Delete []p[i];
			p[i] = nullptr;
		}
		Delete []p;
		p = nullptr;
	}
}

3.如何避免内存泄露

  • 确保没有在访问空指针。
  • 每个内存分配函数都应该有一个 free 函数与之对应,alloca 函数除外。
  • 每次分配内存之后都应该及时进行初始化,可以结合 memset 函数进行初始化,calloc 函数除外。
  • 每当向指针写入值时,都要确保对可用字节数和所写入的字节数进行交叉核对。
  • 在对指针赋值前,一定要确保没有内存位置会变为孤立的。
  • 每当释放结构化的元素(而该元素又包含指向动态分配的内存位置的指针)时,都应先遍历子内存位置并从那里开始释放,然后再遍历回父节点。
  • 始终正确处理返回动态分配的内存引用的函数返回值。

4.内存泄露检测工具valgrind

这是一个linux下的内存泄露检测工具

内存泄露情况:

在这里插入图片描述

 无内存泄露情况:

在这里插入图片描述

c++内存泄露(二):使用性能监视器进行内存泄露的确认_invisible_sky的博客-CSDN博客

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式_笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值