首页 > 代码库 > C++内存管理

C++内存管理

一,内存分配方式

  1. 从静态存储区分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。

  2. 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

  3. 在堆上创建,亦称动态内存分配。程序在运行的时候用 malloc 或 new 申请任意多少的内存,程序员自己负责在何时用 free 或 delete 释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

 

二,常见的内存错误及其对策

  通常是在程序运行时才能捕捉到发生的内存错误,编译器不能自动发现。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。一般常见的内存错误及对策如下:

  1. 内存分配未成功,却使用了它。

  编程新手常犯这种错误,主要是因为他们没有意识到内存分配是否成功,常用的解决方法是在使用内存之前检查指针是否为NULL,如果指针p是函数的参数,那么在函数的入口处使用assert(p != NULL)进行检查。如果是用 malloc 或 new 来申请内存, 应该用 if(p == NULL) 或 if(p != NULL)进行防错处理。

  2. 内存分配虽然成功,但是尚未初始化就引用它。

  犯这种错误的主要起因有,一是没有初始化的概念;二是误以为内存的缺省初值全部为0,导致引用初值错误(例如数组)。

  3. 内存分配成功并且已经初始化,但操作越过了内存的边界。

  例如在使用数组时经常发生下表“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。

  4. 忘记了释放内存,造成内存泄露。

  含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一天程序会突然死掉,系统出现提示:内存耗尽。

  动态内存的申请和释放必须配对,程序中的malloc 与free 的使用次数一定要相通,否则肯定有错误。当然new/delete同理。

  5. 释放了内存却继续使用它。

  有几种这样的情况可以考虑:一是 函数的return语句返回错误,注意不要返回“栈内存”的指针或者引用,因为该内存在函数体结束时会被自动销毁;二是使用free或delete释放内存后,没有指针设置为null,导致产生“野指针”。

 

三,建议

1. 用malloc 或 new 申请内存后,应该立刻检查指针是否为NULL。防止使用指针值为NULL的内存。

2. 不要忘记为数组或动态内存赋初值。

3. 避免数组或指针的下标越界。

4. 动态内存的申请与释放必须配对,防止内存泄露。

5. 用free或delete释放内存后,注意将指针设置为NULL,防止产生“也指针”。

 

摘抄于《C++ 高质量编程指南》,感谢,以此谨记并感谢作者。

 

C++内存管理