每一个应用程序,都有自己的内存空间。例如程序1有程序1的内存空间,程序2有程序2的内存空间,程序1不能访问程序2的内存空间,程序2也不能访问程序1的内存空间。假设钱包是内存,钱包里面的钱是内存中的数据。你不能用别人的钱,因为别人的钱不是你的钱,反过来别人也不能用你的钱,因为你的钱是你个人私有的;而你的钱又分为十元钱,二十元钱,五十元钱,一百元钱,不同面值的钱放在钱包不同的夹层里面,十元钱放在十元钱夹层里面,二十元钱放在二十元夹层里,五十元钱放在五十元夹层里,一百元钱放在一百元夹层里;如果你不加以区分,所有的钱都放在一个夹层里面,是不是很乱呢,我需要五十块钱买东西,直接在五十元夹层里拿就好了,比起将整个钱包翻一遍要快速方便的多。内存也是一样的道理。钱包有四个夹层,而内存也有四个区,不同的区存放不同的数据。
栈区:
栈(stack),是一种先进后出的内存结构,所有的局部变量、函数的形参都是放入栈中,当一个局部变量超出其作用域时,自动从栈中弹出。
栈区存放的是局部变量。
存放在栈区的数据,可以在程序运行期间随时修改。
对与局部变量,什么时候入栈,什么时候出栈,是不需要程序控制的,由编译器控制。而堆则相反。
堆区:
堆(heap)和栈一样,也是一种在程序运行期间随时可以修改的内存区域,但没有栈那样先进后出的顺序。
堆是一个大容器,它的容量要远远大于栈,但是在C/C++中,堆内存空间需要手动的分配及释放(C语言通过malloc函数分配堆内存,通过free函数释放。C++语言通过new关键字分配堆内存,通过delete关键字释放)。
静态区:
静态区存放的是:全局变量、全局静态变量、局部静态变量。
代码区(code):
程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不能在程序运行期间修改的。
代码区存放的是程序的所有可执行代码。
void main() { int i; i = 0; cout << ++i << endl; }
int i; 这句话不是可执行代码,所以不会放入代码区。而是放入栈区,因为i是定义一个局部变量。
除了int i; 这句代码意外,所有的代码都将放入代码区。
看一段代码:
1 #include <iostream> 2 using namespace std; 3 4 int c; 5 void OutPut(const int *p1, const int *p2) 6 { 7 cout << hex << p1 << "\t" << p2 << endl; 8 } 9 int main() 10 { 11 int a; 12 int b; 13 static int d; 14 int *p1 = new int; 15 char *p2 = new char; 16 17 OutPut(&a, &b); 18 OutPut(&c, &d); 19 cout << "p1 = " << p1 << "\tp2 = " << hex << (int)p2 << endl; 20 cout << "main = " << main << "\tOutPut = " << OutPut << endl; 21 22 delete p1; 23 delete p2; 24 25 getchar(); 26 return 0; 27 }
假设:
a的地址 = 0016F738 b的地址 = 0016F72C
c的地址 = 01235510 d的地址 = 01235518
p1的地址 = 005CA0B0 p2的地址 = 005CA010
main的地址 = 0122150F OutPut = 0122125D
请问,变量a、b、c、d、p1、p2、p1指向的内存、p2指向的内存、main函数、OutPut函数都在区?
答:变量a、b在栈区
c,d在静态区
p1,p2在栈区
p1指向的内存、p2指向的内存在堆区
main函数、OutPut函数在代码区