一.C++五个内存分区
(1)栈区:存放两种数据类型,函数的局部变量、函数传递的参数,变量申明周期随函数结束而终结。值得注意的是栈的大小一般是1M大小,所以解释了递归时容易栈溢出;
(2)堆区:这是给程序员使用的,一般2GB大小空间,程序员用new和delete从这2GB空间申请动态空间,有借有还。当用new去借的时候,没有delete,就是典型的内存泄露;
(3)字符常量区:例如定义的char country[] = "中国";字符常量存储在这类区;
(4)全局数据区:全局变量和static定义的静态变量在这里存储;
(5)代码区:用于函数的二进制代码存储。
动态内存分配的原因:正因为栈太小了(1M),所有C++定义了(new和delete)能在堆(2GB)区里面操作,同时也能分配回收节省空间。
二.C++变量的四种存储类型
(1)用的很少的两种:auto局部变量类型,随函数结束而消失;
register寄存器类型,生命周期也是局部的,且不能定义为全局变量。
(2)普遍使用的:static静态变量,作用域在一块函数内,但生命周期是整个程序的时常,即函 数 结束也没有销毁;
exten:像外包一样,把其他cpp的变量引进了使用。
三.C++内存分配和回收常见六种错误
每一种遇到都会很头疼,遇到的话程序员整天跟失恋一样,也是C++同其他语言最难处理的地方之一。
(1)多次释放:
①前面申请了空间int *p[] = new int[18];
②//**** 吭哧坑次的写了一两百行
③ delete[] p;
④//**** 吭哧坑次的又写了一两百行
⑤ delete[] p; //代码太多,你已经忘记了前面已经回收了,运行程序就会卡死
(2)内存泄露:
①前面申请了空间int *p[] = new int[18];
②//***吭哧坑次的写了一两百行,刚想delete,到后面因为该bug忘记delete
(3)释放的不是申请的地址:
①int *p = new int[18];申请空间
②for(int i=0; i<18; i++) p++; //此时p向后移动了18个字节,不是只想原来的地址
③//吭哧坑次的写了一两百行
④delete [] p //回收的不是原来那块门牌号
(4)越界访问:
①int *p = new int[18];申请空间
②for(int i=0; i<18; i++) p++; //此时p向后移动了18个字节
③//吭哧坑次的写了一两百行
④or(int i=0; i<18; i++) p++; //代码太多,忘记前面p已经在地址末尾了,越界了
(5)释放空指针:
①int *p = NULL;
② if( true ) p = new int(10);
else XXXX
③//吭哧坑次的写了一两百行
④delete p; //前面写了new,后面想当然会写delete,注意条件假没有累内存
(6)释放了之后又使用:
①int *p = new int(10);
②//吭哧坑次的写了一两百行
③int *p = new int(10);
④//吭哧坑次的写了一两百行
⑤int a = *p; //经理叫去改完bug,忘记了前面已经释放了