C/C++ 中的堆和栈分别是什么?
前言本人是一位单片机软件工程师在这里记录一下自己的学习笔记。文档中可能存在不足或错误的地方欢迎大家批评指出谢谢一、什么是堆栈?说到堆栈肯定跟内存分区有关系。据所周知我们编写的代码中的函数、局部变量、全局变量、常量都是要占内存的。内存又可以分为四个区代码区、数据区、堆区、栈区。代码区在程序运行前加载到内存中这块内存是只读的。1、函数定义void test()...2、结构体定义struct Data{}...3、类定义class Man{}...如果想用指针去修改这部分内存就会爆炸错误示范:void test(){} char* p (char*)test; *p 48;数据区逻辑上连续的内存常量字符串也是只读的1、全局常量const int g_num1;2、全局变量int g_num2;3、常量字符串常量字符串4、静态变量static int num 30;常量字符串也是只读的如果又想用指针骚操作也是不行的。强行修改也会炸错误示范char* p (char*)我是一个大帅哥; *p 6;除此之外其他的全局变量甚至是const修饰的都可以用指针骚操作了。正确示范;const int g_num1; int* p g_num1; *p 666;堆区用malloc和new关键字申请的内存存放在堆区注堆区内存申请了不用必须要记得释放int*p (int*)malloc(200); char* data new char[2000]; free(p); delete[] data;堆区的大小是动态增长的申请内存时只要系统有富余内存就可以申请得到。所以堆区的内存块是不连续的。栈区栈区是程序启动时就已经分配好的一块内存大小是固定的。通常容量很小在windows上的是1MB在Linux上是8MB。栈区里面是如何存放的呢void test2(int count){ int a 40; } void test1(int num){ static int s_num 50; int a 30; test2(num); } int main(){ int a 20; test1(a); return 0; }看这样一段代码黑框表示栈区。1、int a 20; 这时候就会把a这个变量压入栈帧。这个局部变量存储在栈区2、test1(a); 这句时会生成一个新的栈帧。同时把当前test1的调用地址压到最顶的栈帧中作为返回地址。3、同时传入一个参数a相当于生成了一个变量压到这个栈帧中用来接收外部传进来的值。4、static int s_num 50; 这是个函数内的局部变量存在数据区中存在于整个程序的生命周期。5、int a 30 创建了一个局部变量也是存放于该栈帧中。6、test2(num); 此步调用其他函数就会生成新的栈帧同时把地址压进去。7、同时传入一个参数num相当于生成了一个变量压到这个栈帧中用来接收外部传进来的值。8、int a 40 局部变量继续放在顶部栈帧中栈区就是用来存储程序返回地址、参数、局部变量的。因为由于栈帧的保护是的不用函数里的同名局部变量都能正确访问自己的内存互不干扰。二、大坑坑点1假如在test1中返回局部变量的指针会怎么样呢void test1(int num){ static int s_num 50; int a 30; test2(num); return a; }答案也一样是会爆炸因为你指向的内存已经被回收掉了这块内存会被后面运行的其他代码给覆盖掉。所以说千万別返回一个局部变量的地址来使用。点坑点2栈区还有一个坑点就是栈区的空间非常小如果存满再继续存的话就会导致栈溢出导致程序崩溃。举例1使用局部变量声明大内存数组int main(){ char buff[2000000]; }举例2递归函数导致的真层次调用void test(int num){ if(num 0){ test(num - 1); } } int main(){ test(10000); }三、总结代码区和数据区在程序运行前已经加载了大小固定逻辑上这两个区的地址是连续的处于低地址。接着是堆区运行过程中是动态改变的处于较高的地址上。最后是栈区大小固定占用情况可变处于高地址上。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2408212.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!