C内存管理一 概述

我们写了这么多年的程序员,可能理论方面还比不上大学生。有人 "嘘"我了,如果有能回答以下几个问题的同学请举手: 1.面试经常遇到:同学请说说堆栈的区别? 2.同学请说说一个函数在堆栈中调用过程(首先要知道函数过程是保存在什么中的)。 3.静态变量、全局变量、局部变量、常量等哪些是保存在堆中,哪些是栈中,哪些是静态区域中。 其实回答第一个我问题,第二和第三问题就是........还真有人举手。就算你举手了,我也要讲,有不对的地方,这几位同学给我批评指正。 先来看图:

就上图来看堆栈区别是.......很明显堆比栈大。(别嘘),操作系统太高深此处省略,其它还有文字常量区、程序代码区,在其他我也不知道有什么此处省略。我们专门来看看 栈、堆、静态存储区。准备好了吗?

什么是堆,什么是栈

堆--heap  栈--stack  最大的区别:一个四个字母,一个5个字母。

宏观上来说。栈是由系统提供的数据结果,而堆是由C/C++函数库提供的。

从这句话中我的猜测理解是栈是系统提供和管理的,而堆是编程语言提供和管理的。在浓缩一下就是栈是自动管理的,而堆是手动管理的。

微观上来说。堆栈就是一种方式,一种存储数据的方式或者一种数据结构。

看它的定义:栈是一种先进后出的线性表,只要符合先进后出的原则的线性表都是栈。

而堆是一种二叉树,有最大推、最小堆,我们常用的什么冒泡、选择等可以用于堆排序。

总之浓缩一下:

栈是系统自动管理、采用先进后出方式存储数据的存储区域。而堆是采用手动管理(malloc 和 free程序中创建、释放)、采用二叉树存储数据的存储区域。(特殊情况除外,比如栈也有动态分配和静态分配)

栈是一种先进后出的线性表,只要符合先进后出的原则的线性表都是栈。

综上:栈的特点就是快速、高效、但是由于是机器读写,灵活性相对较弱。堆由于可以手动大小分配,较为灵活、使用面广泛,但是速度没有栈快。

堆栈区别

1、分配方式:自动、手动 2、速度、大小、响应速度:栈快、小,堆慢、大 3、数据存储方式:先进后出、二叉树

补充说明:静态存储区似乎给忘了,只要记住一点静态存储区是用来存放全局变量和静态变量的。

程序中哪些是放在堆中、哪些是放到栈中

1、栈区(stack): 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。   例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间例如:声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间 2、堆区(heap): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。 需要程序员自己申请,并指明大小,在c中malloc函数 如p1 = (char *)malloc(10); 在C++中用new运算符 如p2 = (char *)malloc(10); 但是注意p1、p2本身是在栈中的。例如:在c中malloc函数  p1 = (char *)malloc(10);  p1 = (char *)malloc(20);  但是注意p1,p2本身是在栈中的。 到此我的猜测----栈中存储的大部分是地址(还有写少许的局部变量值)。 3、全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 (程序结束后有系统释放 ,即生命周期) 4、文字常量区 —常量字符串就是放在这里的。 5、程序代码区—存放函数体的二进制代码。 程序说明: int a = 0; //全局初始化区  char *p1; //全局未初始化区 

[html] view plaincopyprint?

  1. main()   
  2. {   
  3.   int b; //栈   
  4.   char s[] = "abc"; //栈   
  5.   char *p2; //栈   
  6.   char *p3 = "123456"; //123456在常量区,p3在栈上。   
  7.   static int c =0; //全局(静态)初始化区   
  8. p1 = (char *)malloc(10);   
  9. p2 = (char *)malloc(20);   
  10.   //分配得来得10和20字节的区域就在堆区。   
  11.   strcpy(p1, "123456"); //123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。   
  12. }   

函数调用过程

函数调用主要是在栈中进行的:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏黄成甲

怎样科学地和人相处?

按照约定俗成的说法,一般跟人打交道有两个规则,一个是“黄金法则”,一个是“白银法则”。黄金法则并不适合现代社会对陌生人使用。因为你觉得好的东西别人不一定觉得好。...

16020
来自专栏進无尽的文章

什么才是优秀的网站用户界面设计

17420
来自专栏计算机编程

2018-03-14 致敬霍金

  在黑洞领域,没有人知道这个怪兽是个什么东西,自从霍金给出“霍金辐射”与“奇点定理”过后,人们终于逐渐揭开了这宇宙中最为神秘的天体。在这里再次缅怀一下虽然坐着...

15320
来自专栏数据库新发现

思科CEO钱伯斯:我非常尊敬华为

--------------------------------------------------------------------------------...

32310
来自专栏黄成甲

怎样成为解决问题的高手(连载一)

什么是问题?一言以蔽之,问题来源于现实与目标的差距。因此,问题产生的原因可能是不清楚目标是什么;还可能是不知道差距产生的原因是什么;或者虽然知道差距产生的原因,...

35440
来自专栏一个会写诗的程序员的博客

服务网格 Pattern: Service Mesh

自从几十年前首次引入以来,我们了解到分布式系统能够实现我们之前甚至无法思考的用例,但它们也会引入各种新问题。

14520
来自专栏知道一点点

20种新颖的按钮风格和效果【附源码】

Codrops 给我们分享了一组新鲜的按钮样式和效果的集合。它们中的大部分效果都使用了 CSS3 过渡和伪元素,他们都有一个共同点,那就是都具有简单性,没有太多...

16910
来自专栏数据库新发现

第十三届搞笑诺贝尔奖(IgNobel)新鲜出炉

第十三届搞笑诺贝尔奖(IgNobel)新鲜出炉 中广网 10月04日 09:48

19330
来自专栏Leetcode名企之路

【Leetcode】59. 螺旋矩阵 II

给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

16030
来自专栏進无尽的文章

益思维-早期苹果员工胸牌背面写的11条“成功法则”

早期苹果员工胸牌背面写的11条“成功法则”这个胸牌的背面写着11条成功法则,其中每一条文字都充满了正能量。从中我们可以看到一些触动人心的感觉。

10120

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励