C++ 栈 与 堆
1.两者都表述为内存空间时:
stack 栈,是存在于作用域中的内存空间。若作用域实现某个动作,它需要一定内存 ,
其中包含一些数据或对象,直接在该内存段中创建(例如仅需一个int),就是栈内存。
即,可认为在函数本体内声明的变量 所用内存 为栈内存。
heap 堆,由操作系统提供的 一块 全局内存空间(应当是较大空间),用于程序实现
动态申请若干内存,对比 栈,在函数内声明一个指针,申请作用域外内存空间(例如需
一个较大的数组),而作用域内只有所需数据或对象的地址。
create()
{
char a = 's'; //申请栈内存
char* b = new char[100]; //申请堆内存
.... //
delete [] b; //手动处理堆内存 b指向的内存
} //自动处理 a,b (存放a,b的内存)
2.两者生命周期:
栈
由于本身属于作用域内存的一部分,因此在作用域(所在代码块)结尾自动随作用域内存被处理而被处理。
在声明变量或对象时,使用了限定词:static,该变量或内存,将不随作用域结束而被处理,而是与整个程序的生命周期并存。
堆
由于作用域内仅包含指针,因此在作用域过期时仅自动处理掉指针数据(存储了一个地址),而它指向的那个地址上的数据仍然存在。
3.两者处理:
两者区别可以看做其生死大权的掌控者不同。
栈内存由所在 代码块 控制,同生共死(自动处理),添加static限定词后,被程序控制,与 程序 同生共死。因此对于栈内存,不需额外操作处理。
堆内存由操作系统和程序员 控制其存在,由代码块中的指针来从堆中说明其身份,但 指针 却是代码块中的栈内存,在代码块结束后消失,堆内存将无人知晓其身份和地址,也就没人能清理它(或操作系统这个程序结束),而另一个程序不幸又申请到它,但他的身份只满足前一个已消失的指针,这将对新的程序造成不可预知的问题。
所以需额外处理它。在申请它的指针所在代码块中,通过知晓它身份的该指针来处理,即使用 delete 。
注:delete该指针,包括考虑指向的类型。
指针指向数组
int * a = new int[10];
delete [] a;
指针指向对象
int * a = new int(5);
delete a;
注:在对象创建时new的考虑:
String * str = new String(“sssssss”);
先处理new,分配相应内存,再处理String()构造函数,创建对象,初始化,传递地址。
delete str;
先取消内存块的身份(调用对象析构函数),再内部释放内存。