今天去面试,面试官再一次问到了对堆栈的理解这个问题,答的不是太好,在网上又查阅了一些讲的比较清楚的博客,现在来梳理一下内容,以备下次之需。
一个由C/C++编译的程序占用的内存包括下列几项:
- 栈区(stack)
- 堆区(heap)
- 静态区(全局区)
- 常量区
- 代码区
它们在内存中的地址由低到高顺序为 5-4-3-2-1
其中
栈区、堆区、静态区存放在
RAM中
常量区、代码区 存放在
ROM中
代码区
- 代码区的内存由系统控制
- 代码区的地址是函数的地址、程序的入口地址、函数的名字
常量区
以上代码定义了一个char *型的指针temp,temp存放的是字符串常量“Hello World”的首地址,“Hello World”是存放在常量区的,也就是temp是指向常量区的。那么temp里的内容是不可以被修改的。在gcc下无法运行以上代码。
静态区(全局区)
a是静态全局变量,b是全局变量,c是静态局部变量,它们都存放在静态区。运行结果如下:
a和b都未初始化,打印出来为0,说明编译器自动把它们初始化为0,c初始化为1,在for中循环初始化3次,但实际只初始化一次,后面每次都是调用c上一次的值,且c的地址是不变的。
堆区
堆区调用malloc()函数来申请用户所需内存,内存使用完毕后调用free()函数释放内存。堆区地址向上增长。
栈区
栈区由编译器自动分配释放,存放函数的参数值,返回值及局部变量。栈区是向下增长的,所以是先进后出原则。
左为ROM(flash)大小,右为RAM大小。
如上图
- Code是程序代码所占的字节
- RO-data是只读数据,程序中的常量区
- RW-data是已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处,一部分静态区
- ZI-data是未初始化的读写数据,程序中定义但未初始化的全局变量和静态变量位于此处,另一部分静态区
Total ROM=Code+RO-data+RW-data即下载到flash的数据大小。