C++程序中的内存分为分为两个部分———堆栈(又叫栈)和堆。堆栈就像一副扑克牌,当前顶部的牌代表程序的当前的作用域,通常也是当前正在执行的函数。当前函数中声明的所有变量将会占用顶部栈帧(也就是最上面的牌)的内存。
堆栈会为每一个函数提供独立一块连续的内存的空间,是数据暂时储存的地方,栈中元素个数为零时称为空栈。向一个栈插入新元素又称作进栈,入栈或压栈,它把新元素放到栈顶元素的上面,称为栈顶元素;从一个栈删除元素又称作出栈或退栈。如果在一个函数栈堆里,声明一个变量,那么除非专门需求,否则调用其他函数不会改变改变量。此外,在该函数执行完毕时,堆栈就会消失,该函数中声明的所有变量都不会在占用内存。在堆栈分配内存的变量不需要程序员释放内存(删除),这个过程是自动完成的。
在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
栈中的数据大小与生存期必须是确定的
例如:
int fun(int num1, int num2) { int nNum = 10; return 0; } //nNum就会在函数fun调用结束后释放,生存期消失。堆是当前函数或者堆栈完全没有关系的内存区域。如果想在函数调用结束之后任然保存其中声明的变量,可以将变量放到堆中。程序可以任何时候向堆中增加新的或者修改已有的位。必须确保释放(删除)在堆上分配的任何内存,这个过程不会自动完成,除非使用智能指针。 手动分配和释放。是不连续的内存区域,它是在程序运行时而不是在程序编译时申请某个大小的内存空间。堆没有先进后出的原则,可以随时进行增加变量和删除变量,存储速度相对慢些。
例如:
char* szbuff = new char[100*sizeof(char)]; //szbuff 在栈上,分配来的大小在堆区。(手动释放时要用delete) delete [] szbuff;注意:在编译器中 delete 后面的括号表明所删除的是一个数组。
注:在栈上的数组访问比指针所指向的字符串访问快。大家可以自己去看看对应的汇编代码,比较两者的汇编代码执行条数,前者比后者少。
栈上的空间是自动分配自动回收的,所以栈上的数据的生存周期只是在函数的运行过程中,运行后就释放掉,不可以再访问。而堆上的数据只要程序员不释放空间,就一直可以访问到,不过缺点是一旦忘记释放会造成内存泄露。