内存溢出、内存泄露、野指针、空指针
2023-02-18 16:41:48 时间
彻底理清内存溢出,内存泄露,野指针和空指针
内存溢出
看到下面代码的情况,如果使用while循环一直调用GetMemory,一直malloc内存,但是没有使用free函数释放内存,会导致最后没有空间分配,产生的这种情况就是内存溢出
#include <stdlib.h>
#include <iostream>
using namespace std;
void GetMemory(char *p, int num)
{
p = (char*)malloc(sizeof(char) * num);//使用new也能够检测出来
}
int main(int argc,char** argv)
{
char *str = NULL;
GetMemory(str, 100);
cout<<"Memory leak test!"<<endl;
//如果main中存在while循环调用GetMemory
//那么问题将变得很严重
//while(1){GetMemory(...);}
return 0;
}
内存泄露
内存泄露往往是对指针操作不当出现的,没有正确回收
- new和delete,malloc和free没有成对的出现,也就是没有正确回收
{
int *p = new int[100];
delete p;//new[],delete []不匹配,导致99对象的内存空间被泄漏。
delete []p; //这里正确使用
}
- 调用void *类型的对象,导致没有调用对象的析构函数,内存没有回收
class Object {
private:
void* data;
const int size;
const char id;
public:
Object(int sz, char c):size(sz), id(c){
data = new char[size];
cout << "Object() " << id << " size = " << size << endl;
}
~Object(){
cout << "~Object() " << id << endl;
delete []data;
}
};
int main() {
Object* a = new Object(10, 'A');//Object*指针指向一个Object对象;
void* b = new Object(20, 'B');//void*指针指向一个Object对象;
delete a;//执行delete,编译器自动调用析构函数;
delete b;//执行delete,编译器不会调用析构函数,导致data占用内存没有得到回收;
return 0;
}
- 没有将子类的析构函数设置为虚函数,导致某些情况,例如使用子类实例化基类对象时,delete基类只会调用基类的析构函数,具体可以看这里
#include <iostream>
using namespace std;
class Father
{
public:
Father() { cout << "contructor Father!" << endl; };
~Father() { cout << "destructor Father!" << endl; };
};
class Son :public Father
{
public:
Son() { cout << "contructor Son!" << endl; };
~Son() { cout << "destructor Son!" << endl; }; //需要设置为析构函数
};
int main()
{
Father *pfather=new Son;
delete pfather;
pfather = NULL;
return 0;
}
//ontructor Father!
//contructor Son!
//destructor Father!
野指针和空指针
野指针的情况
- 指针没有初始化为某个对象或者nullptr或者NULL
- 指针被delete后没有置空,也就是设置NULL或者nullptr
char *p = (char *)malloc(10);
strcpy(p,"hello");
free(p); //p所指的内存被释放,变为垃圾内存(不可用内存),但是p所指的地址没变。
//p=NULL 应该加上这样一句
if(p != NULL) //没有起到防错作用
strcpy(p,"world"); //篡改动态内存区,后果难以预料,非常危险
- 指针超过了作用域返回,导致指针不知道指向了谁
class A
{
public:
void Func(void){ cout << “Func of class A” << endl; }
};
void Test(void)
{
A *p;
{
A a;
p = &a; // 注意 a 的生命期,过了{}即被回收
}
p->Func(); // p是“野指针”
空指针一般就是指针没有初始化为某个对象,导致使用的时候异常,或者类似野指针中的3情况,指针被回收了,其实对象是空的
相关文章
- 论文速递2022.8.17!
- Disco Diffusion VS Stable Diffusion效果对比! 论文速递2022.8.18!
- 论文速递2022.8.19!
- 论文速递2022.8.22!
- 论文速递2022.8.23!
- DataGrip激活码,DataGrip2022最新_DataGrip使用说明
- 帅爆! 赛博朋克特效实现
- 论文速递2022.8.24!
- STABLE Diffusion 权重公布! 注册可下载使用论文速递2022.8.25!
- 论文速递2022.8.26!
- CVPR2022 | 视频摩尔纹去除 ! 论文速递2022.8.29!
- [javaEE] EL表达式调用java方法
- 赛博朋克特效实现 ! 附源码
- [javaEE] EL表达式获取数据
- 输入位置,控制 StyleGAN 生成图像的布局! 论文速递2022.8.31!
- 论文速递2022.9.1!
- 论文速递2022.9.2!
- X-NeRF!一种基于神经辐射场公式的学习交叉光谱场景表示的新方法! 论文速递2022.9.5!
- ECCV2022 | SimpleRecon 无需 3D 卷积的高质量三维重建方案! 论文速递2022.9.7!
- 交通灯数据集,涵盖城市和郊区! 论文速递2022.9.8!