C++:内存分区模型&常见内存错误

C/C++内存分布图

用户并不能使用所有的内存空间,内存空间被划分为用户态(用户自己的信息)和内核态(与系统相关的信息)
对内存区域划分的原因:便于信息和数据管理

在这里插入图片描述

  • C++程序在执行时将内存划分成4个区域
  • 划分意义:不同区域存放数据,赋予不同的生命周期,使编程更灵活
代码区存放函数体的二进制代码,由操作系统进行管理
全局区存放全局变量,静态变量,常量
栈区由编译器自动分配释放,存放函数参数,局部变量
堆区由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

程序在运行前只有代码区和全局区,运行后才会有栈区和堆区

内存泄漏

指程序未能释放掉不再使用的内存。
内存泄漏并不是内存在物理意义上的消失,而是程序分配某段内存后,失去了对该段内存的控制造成的

内存泄漏的分类

(1)堆内存泄漏:
程序运行时通过malloc/new等从堆中分配的一块内存,使用完成后必须通过调用相对应的free/delete释放掉。
如果这部分内存没有被释,那么这块内存不会被使用,从而导致堆内存泄漏。

(2)系统资源泄漏
程序使用系统分配的资源比如socket等没有使用相应的函数释放掉,导致系统资源的浪费

(3)没有将基类的析构函数定义为虚函数。
当基类指针指向派生类的对象时,如果基类的析构函数不是虚函数,那么子类的析构函数将不会被调用,子类的资源没有被正确释放掉,造成内存泄漏。

如何判断内存泄漏

使用linux下的内存泄漏检查工具来判断内存是否泄漏
在写代码时添加内存申请和释放的统计功能,来统计当前申请和释放的内存是否一致,从而来判断内存是否泄漏。

段错误

段错误通常发生在访问非法内存地址的时候,即使用了野指针(指向一个已删除的对象或者未申请访问受限内存区域的指针)或这试图修改字符串常量的内容。

内存溢出

内存溢出指程序在申请内存时,没有足够的内存供申请者使用

内存溢出原因

(1)内存中加载的数据量过于庞大,如一次性从数据库取出过多数据。
(2)集合类中有对对象的引用,使用后未清空,使得不能回收。
(3)代码中存在死循环或循环产生过多重复的对象实体。
(4)使用的第三方软件中的bug
(5)启动参数内存值设定的过小

栈溢出

由于递归或循环嵌套层次太多造成的

栈溢出的现象

(1)局部数组过大。当函数内部的数组过大时,有可能导致栈溢出。

(2)递归调用层次太多。递归函数在运行时会执行压栈操作,当压栈次数太多时,也会导致栈溢出。递归求第1000项的斐波那契数造成栈溢出。

(3)指针或数组越界。例如进行字符串拷贝

解决办法

1.增大栈空间
2.改用动态分配
3.使用堆而不是栈

堆溢出

不断的new 一个对象,一直创建新的对象,但是不销毁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值