常见内存泄漏场景与解决方案

服务器开发文章目录



前言

作为C/C++程序员,谁还不写Bug,Bug中最常见要数内存泄漏、内存崩溃、死锁等问题,本文主要讲解内存泄漏问题,其具有其独有的属性,比如说:隐蔽性强、难以排查、占用资源不断累积等特点,当到达一定程度会出现崩溃、被系统kill掉等……
请添加图片描述


一、内存泄漏是什么?

内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

二、常见内存泄漏场景

场景1:new/malloc与delete/malloc没有成对出现

void callfun(char *p)
{
	std::cout<< p<<std::endl; 
}
void fun()
{
	char *p = new char[128];
	return callfun(p);    
}

场景2:new/malloc 提前返回

void fun(std::string request)
{
	char *p = new char[128];
	if(request.length()== 0){
		return;
	}
	delete []p;
   	return;
}

场景3:基类被继承时,虚构函数没有被定义为virtual

class A
{
public:
	A(){}
	~A(){}      //未定义virutal
};
class B:public A
{
public:
	B(){
		p = new char[128];
	}
	~B(){
		if(p) delete [] p;
		p = nullptr;
	}
private:
	char *p = nullptr;
};

int main()
{
	A* inst = new B;
	...
	delete inst;
	return 0;
}

场景4:类对象通过shared_ptr<>相互引用

class A
{
public:
    A() {}
    ~A() {}
 publpic:
    int _data = 0;
    std::shared_ptr<A> _next;
}
int main()
{
	shared_ptr<A> n1(new A);
	shared_ptr<A> n2(new A);
	n1.get()->_next = n2;			// 代表深蓝色的线所做的事(n1结点的下一个指向n2)
	n2.get()->_next = n1;			// 代表浅蓝色的线所做的事(n2结点的下一个指向n1)
	return 0;
}

场景5:引用第三方接口分配资源,没有调用释放资源接口

char *mallocresource(int len);
void demallocresource(char *p)


int fun()
{
	char* p = mallocresource(100);
	//do something
	return 0;
}

场景6:未关闭文件句柄

int readFile()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL){
		perror("fopen");//输出错误原因,双引号里为要检查的函数
		return -1;
	}
	fseek(pf, 9, SEEK_SET);//文件指针偏移  SEEK_SET初始位置开始偏移
	int ch=fgetc(pf);        //SEEK_CUR  当前位置开始偏移
	printf("%c\n", ch);      //SEEK_END  末尾位置开始偏移
	return 0;
}

场景7:释放对象数组时在delete中没有使用方括号

class A
{
public:
	A(){
		p = new char[128];
	}
	~A(){
		if(p) delete p;
		p = nullptr;
	}
public:
	char *p;
};
int func()
{
	A* P = new A[100];
	delete p;
	return 0;
}

场景8:stl中value指针没有被delete释放

class A
{
public:
	A(){
	}
	~A(){
	}
};

std::map<std::string,A*> Avec;
void fun(){
	Avec.emplace("1",new A());
	***
	Avec.clear();
}

三、内存泄漏规避与定位

如何规避内存泄漏问题
1、通过智能指针来规避大部分内存泄漏问题
如何定位内存泄漏问题
1、通过代码打印,打桩封装malloc与free等接口,发现哪个模块没有内存分配没有成对(麻烦不推荐)
2、仔细评审两个版本间的代码差异,看看哪个地方疏忽等原因引入了内存泄漏,工作量打不推荐。
2、valgrind工具来定位、或asan工具等,细节略。


总结

通过上面的介绍,应该对常见的内存泄漏问题有了一点的了解,希望对你以后开发的过程中有所帮助。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

c+猿辅导

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

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

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

打赏作者

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

抵扣说明:

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

余额充值