C++ 野指针从何而来?内存泄露有哪些坑需要避免?

本文探讨了C++中的内存分配方式,包括栈、堆、自由存储区、静态存储区和常量存储区,并重点分析了野指针产生的原因和常见的内存错误,如资源泄露、内存越界等问题,提供了避免内存泄露的建议和正确使用malloc和new的方法。
摘要由CSDN通过智能技术生成

 
 指针问题一直是C++工程中的让人头疼的问题,动不动给你报个"段错误",都不知道从何查起.这篇博客就C++中野指针的产生原因以及如何有效避免内存泄露的一些坑作一些总结,希望以后学习工作中,养成指针定义即初始化的好习惯,彻底理解内存的正确分配和释放方式,从源头避免内存泄露的问题.
 

一. 内存分配方式

1. 五个内存区

  • : 栈是线程独有的,每个线程的栈相互独立,每个函数都有自己的栈,栈由编译器自动分配和释放,存储通常定义的局部变量,特点是自动申请,自动释放,效率高,容量有限;
  • : 堆是大家共有的空间,程序猿手动使用malloc申请的内存,特点是手动申请(malloc),手动释放(free),效率较低,容量较大,只负责申请内存,无初始化;
  • 自由存储区: 程序猿手动使用new申请的内存,特点是手动申请(new),手动释放(delete),效率较低,容量较大,申请内存,同时可调用构造函数初始化;
  • 静态存储区: 全局变量,全局/局部静态变量,全局变量在main函数之前申请,局部静态变量在执行到该位置时开始申请,都在整个程序运行结束,才释放内存.
  • 常量存储区: 常量池,不允许修改.

2. 正确使用malloc和new

2.1 malloc
  • 原型: extern void *malloc(unsigned int num_bytes);
  • 说明: 分配长度为num_bytes字节的内存块。如果分配成功则返回指向被分配内存的指针,分配失败返回空指针NULL.
  • 判断: 申请之后务必判断是否申请成功,使用if(p != NULL){}
  • 释放: free(p); p = NULL;
  • malloc只负责申请内存,不知道用户申请的是何种类型,返回void,用户需要用强制类型转换成想要的类型*.
int *p = (int*)malloc(sizeof(int)* 2);//申请了4个int大小的内存空间
if(p == NULL)//判断是否申请成功
	exit(-1);
//赋值
p[0] = 1;
p[1] = 2;
cout << "p: " << *p << " " << *(++p) << endl;
free(p);//释放,此时p是一个悬挂指针
p = NULL;
2.2 new
  • 说明: 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算;
  • 判断: 申请之后务必判断是否申请成功,使用if(p != NULL){};
  • 申请失败: new内存分配失败时,会跑出bac_alloc异常,不会返回NULL;
  • 释放: delete p; p = NULL;或者delete[] p; p = NULL;
  • new负责申请内存,自动计算内存大小,返回用户指定的类型.
int *p = new int;//申请一个int类型的指针,未初始化
int *p2 = new int(); //申请一个int类型的指针,初始化为0
int *p3 = new int(10);//申请一个int类型的指针,初始化为10
int *p4 = new int[10];//申请一个int类型的数组,未初始化
int *p5 = new int[10]();//申请一个int类型的数组,初始化为0
int *p6 = new int[10]{
   1,2,3,4};//申请一个int类型的数组,前四个初始化为1,2,3,4,后面初始化为0
for(int i = 0;i < 10;i++)
	cout << p6[i] 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值