c++内存管理(整理自网络)

内存分配方式

执行函数时,函数局部变量存储单元都在栈上创建,函数执行结束时自动释放。栈内存分配运算置于处理器的指令集中,效率很高,但容量有限。
由new分配的内存块在堆上创建,由delete释放。如果程序员没有释放掉,程序结束后由操作系统回收。
自由存储区 和new类似,是由malloc分配的内存块,用free释放。
静态存储区存放全局变量和静态变量。
常量存储区存放常量,不允许修改。

堆与栈的区别

区别
管理方式 编译器自动管理 程序员手动释放,容易产生内存泄漏
空间大小 32位系统下,可达4G 1M~2M
碎片问题 频繁new delete造成空间不连续 栈先进后出,空间连续
生长方向 向上(内存地址增加) 向下(内存地址减小)
分配方式 动态分配 静态和动态
分配效率 C/C++函数库提供,低 底层提供支持,高

C/C++函数库提供,如为分配一块内存,库函数会按照一定算法再堆内存中搜索可用的足够大小的空间,如果没有就调用系统功能增加程序数据段的内存空间,效率低
机器系统提供的数据结构,计算机在底层提供支持:分配专门的寄存器存放地址,有专门指令执行,效率高

内存池

new delete

为什么要重载
和malloc&free的区别
1. malloc&free是C/C++标准库函数,不在编译器控制范围内,new&delete是C++运算符,可以申请动态内存和释放内存。
2. 对于非内部数据类型的对象而言,malloc/free无法满足动态对象的要求。
3. 对象创建时执行构造函数函数,消亡前执行析构函数。因此需要能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。
4. 为什么不淘汰malloc/free,因为c++经常调用c函数,c程序只能用malloc/free管理动态内存

void UseMallocFree(void)
{
 Obj *a = (obj *)malloc(sizeof(obj)); // 申请动态内存
 a->Initialize(); // 初始化
 //…
 a->Destroy(); // 清除工作
 free(a); // 释放内存
}

void UseNewDelete(void)
{
 Obj *a = new Obj; // 申请动态内存并且初始化,模拟构造函数功能
 //…
 delete a; // 清除并且释放内存,模拟析构函数功能
}

常见错误&对策

  1. 内存分配未成功却使用
    使用前检查指针是否为NULL进行防错处理
    • 如果指针p是函数参数,则函数入口处用assert(p!=NULL)
    • 如果使用malloc或new申请内存,应该if(p==NULL)或if(p!=NULL)检查
  2. 内存分配成功未初始化
    内存缺省初值没有统一标准。
  3. 内存分配成功且初始化,但越界
    尤其在for循环中
  4. 忘记释放内存,内存泄漏
    直到内存耗尽。malloc和free,new和delete配对使用
  5. 释放内存继续使用
    • 对象调用关系复杂,应重新设计数据结构,解决对象管理混乱的局面
    • 不能return指向栈内存的指针或引用
    • free或delete释放了内存后,没有把指针置空,产生野指针

内存耗尽

如果申请动态内存时找不到足够大的内存,malloc和new将返回NULL指针。
处理
- 判断NULL,如果是则用return终止
- 判断NULL,如果是则用exit(1)终止整个程序
- 为malloc/new设置异常处理函数

不编写出错程序,操作系统自己解决?
不行,32位以上应用程序,无论怎样使用malloc/free,几乎不可能“内存耗尽”,因为32位操作系统支持“虚存”,内存用完自动用硬盘空间代替。

阅读更多
上一篇虚函数和虚函数表
想对作者说点什么? 我来说一句

2010年网易笔试整理(全面)

2010年06月17日 100KB 下载

c++内存管理 c++实现

2011年04月28日 7KB 下载

jQuery使用手册

2008年08月26日 159KB 下载

C++内存管理课件——侯捷老师

2017年07月16日 34MB 下载

没有更多推荐了,返回首页

关闭
关闭