本节参考文献: 《高质量C++编程指南》 林锐
内存分配的方式:
1、从静态存储区域分配。
内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
2、在栈上创建。
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
3、从堆上分配,亦称动态内存分配。
程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
静态和动态内存分配的两个主要区别是:
1、静态对象是有名字的变量,我们直接对其进行操作。而动态对象是没有名字的变量,我们通过指针间接的对它进行操作。
2、静态对象的分配与释放由编译器自动处理。程序员需要理解这一点,但不需要作任何事情。相反,动态对象的分配与释放,必须由程序员显式地管理,相对来说比较容易出错,它通过new和delete两个表达式来完成。
常见的内存错误:
1、内存分配未成功,却使用了它。
2、内存分配虽然成功,但是尚未初始化就引用它。
3、内存分配成功并且已经初始化,但操作越过了内存的边界。
4、忘记了释放内存,造成内存泄露。
5、释放了内存却继续使用它。
常见内存错误应对措施:
1、用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
2、不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
3、避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
4、动态内存的申请与释放必须配对,防止内存泄漏。
5、用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。
数组和指针:
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。
指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。指针远比数组灵活,但也更危险。
1、数组中的常量可以被修改,而指针中的常量不能被修改。编译器发现不了指针常量被修改的错误。
2、数组和指针被复制的时候都只能用strcpy,不能直接用=,比较时也不能用==,应该用strcmp。
3、数组在不作为函数参数传递的时候,它的内存容量为N+1;当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
指针的内存容量为4。这是一个指针变量的字节数,而不是内容的字节数。C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。