Linux下C语言程序的内存布局

以下内容源于C语言中文网的内容学习与整理。如有侵权,请告知删除。

一、C语言内存布局

C程序所占用的内存,可以划分为以下几个部分。

1、栈区(stack)。由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap)。一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统回收。注意它与数据结构中的堆是两回事,分配方式类似于链表。

其中栈区、堆区又合称“动态存储区”,而全局区、文字常量区、程序代码区合称“静态存储区”。动态存储区在程序执行过程中动态分配,大小随之动态变化;静态存储区的大小在程序编译连接阶段就已经确定。

3、全局区或者叫静态区,static)。全局变量和静态变量是放在一起存储的;初始化的全局变量和静态变量在一块区域(全局初始化区),未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(全局未初始化区)。全局区在程序结束后由系统释放。

4、文字常量区。存放一般常量、字符串常量,程序结束后由系统释放。

5、程序代码区。存放函数体的二进制代码。   

二、实例解释

//main.c
#include<stdio.h>
#include<string.h>int  a=0;  //全局初始化区   
char *p1;  //全局未初始化区   int main(int argc,char** argv)   
{   int   b;   //栈   char  s[]="abc";//栈   char  *p2;   //栈   char  *p3="123456"; //123456/0在常量区,p3在栈上   static int c=0;//全局(静态)初始化区   p1=(char*)malloc(10); //分配得到的10和20字节的区域就在堆区p2=(char*)malloc(20);//123456/0放在常量区,编译器可能会将它与p3所指向的"123456" 优化成一个地方   strcpy(p1,"123456");  
}   

三、关于堆与栈的理论知识

1、申请方式

(1)栈

由系统自动分配。比如在函数中声明一个局部变量“int b;”,则系统自动在栈中为b开辟空间。(2)堆

需要程序员自己申请,并指明大小。

在C中使用malloc函数进行申请,如“ p1=(char*)malloc(10); ”。

在C++中用new运算符,如“p2   =   new   char[10]; ”。

注意p1、p2本身是在栈中的。

2、申请后系统的响应

(1)栈

只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

(2)堆

操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。大多数系统会在这块内存空间中的首地址处记录本次分配的大小,因而代码中的delete语句才能正确地释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动将多余的那部分重新放入空闲链表中。 

3、申请大小的限制

(1)栈

在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的。

在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。

(2)堆

堆是向高地址扩展的数据结构,是不连续的内存区域。这是因为系统使用链表来存储空闲内存地址,所以自然是不连续的,而链表的遍历方向是由低地址向高地址。

堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

4、申请效率的比较

(1)栈

栈由系统自动分配,速度较快。但程序员是无法控制的。

(2)堆

堆是使用malloc相关函数或者由new来分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,它直接在进程的地址空间中保留一块内存,虽然用起来最不方便,但是速度快,也最灵活。 

5、堆和栈中的存储内容

(1)栈

在函数调用时,第一个进栈的是函数调用语句的下一条可执行语句的地址,然后是函数的各个参数(在大多数的C编译器中,参数是由右往左入栈的),然后是函数中的局部变量。

注意,静态变量是不入栈的。

当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。   

(2)堆

一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排。

6、存取效率的比较

char s1[] = "aaaaaaaaaaaaaaa";   
char *s2  = "bbbbbbbbbbbbbbbbb";  

上面代码中,aaaaaaaaaaa是在运行时刻赋值的,而bbbbbbbbbbb是在编译时就确定的。在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。

比如:   

#include<stdio.h>int main(int argc,char* argv[])
{   char a=1;   char c[] = "1234567890";   char *p  = "1234567890";   a =  c[1];   a =  p[1];return;   
}   

 对应的汇编代码:

  10:   a   =   c[1];   00401067   8A   4D   F1   mov   cl,byte   ptr   [ebp-0Fh]   0040106A   88   4D   FC   mov   byte   ptr   [ebp-4],cl   11:   a   =   p[1];   0040106D   8B   55   EC   mov   edx,dword   ptr   [ebp-14h]   00401070   8A   42   01   mov   al,byte   ptr   [edx+1]   00401073   88   45   FC   mov   byte   ptr   [ebp-4],al   

第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,再根据edx读取字符,显然慢了。   

7、小结

堆和栈的区别可以用如下的比喻来看出:

使用栈就像我们去饭馆里吃饭,只管点菜(发出申请)、付钱和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作,以及和洗碗、刷锅等扫尾工作。它的好处是快捷,但是自由度小。

使用堆就像是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460891.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微型计算机频繁死机的原因,电脑经常死机是什么原因|电脑经常死机的解决方法...

‍‍电脑出现死机是很常见的一种故障&#xff0c;造成的原因也有很多种。而最近有些用户的电脑经常死机&#xff0c;开机几分钟就死机&#xff0c;有时还会出现蓝屏&#xff0c;这到底是怎么回事呢&#xff1f;电脑经常死机是什么原因呢&#xff1f;下面小编结合自己的实际情况…

PKI系统深入介绍

公钥基础设施&#xff08;Public Key Infrastructure&#xff0c;简称PKI&#xff09;是眼下网络安全建设的基础与核心&#xff0c;是电子商务安全实施的基本保障&#xff0c;因此&#xff0c;对PKI技术的研究和开发成为眼下信息安全领域的热点。本文对PKI技术进行了全面的分析…

html 禁止缩放 ios10,完美解决ios10及以上Safari无法禁止缩放的问题

完美解决 ios10 及以上 Safari 无法禁止缩放的问题转载自掘金-互联网学徒移动端web缩放有两种&#xff1a;双击缩放双指手势缩放在 iOS 10之前&#xff0c;iOS 和 Android 都可以通过一行 meta 标签来禁止页面缩放&#xff1a;但 iOS 10开始&#xff0c;meta 设置在 Safari 内无…

SCRT软件的使用教程

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 SCRT软件下载&#xff1a;提取码1234 快速链接的步骤与设置 先选择“快速链接”&#xff1b; 然后协议选serial&#xff0c;端口在设备管理器中查看&#xff08;我的是com3&#xff09;&#xff0c;波特率…

KEIL4.12中添加ULINK2的支持

转载自&#xff1a;http://www.amobbs.com/thread-4767650-1-1.html 如果你用KEIL4.12&#xff0c;但却没有Ulink2下载器&#xff0c;只有早先用的Ulink下载器&#xff0c;那么你按照下面三步升下级就可以了....三步&#xff1a;1.把‘keil-ulink升级至ulink2的文件’解压缩后拷…

解决Vmware中安装Ubuntu Server 14.04 分辨率无法全屏问题

2019独角兽企业重金招聘Python工程师标准>>> We will have to edit grub configuration. Open a terminal and paste this: sudo gedit /etc/default/grub Hit Enter. It will open grub preferences in Gedit.Locate the line # GRUB_GFXMODE800x600 (resolution m…

GCC编译器的相关内容

本文摘录与整理于C语言中文网的相关内容&#xff0c;仅用于学习&#xff0c;如有侵权请告知删除。 原内容网址&#xff1a;C语言中文网&#xff1a;C语言程序设计门户网站(入门教程、编程软件) GCC官方文档网址&#xff1a;Top (Using the GNU Compiler Collection (GCC)) 1、…

计算机用户登录设置成2000,2008计算机等级考试:Windows2000系统选项设置

在Windows 2000 Server中&#xff0c; 用户除了可以进行前面章节中介绍的系统设置&#xff0c;还可以在系统中进行一些其他的设置&#xff0c;包括新建、编辑、删除用户及系统变量&#xff0c;设置默认启动系统及故障恢复选项&#xff0c;查看系统性能等。本节便来介绍一些比较…

成都电讯学院研发的计算机,成都电讯工程学院

[拼音]&#xff1a;chengdu dianxun gongcheng xueyuan[外文]&#xff1a;Chengdu Institute of Telecommunication中国一所以培养电子科学技术人才为主的多科性理工科高等学校。1956年9月创建于四川成都。建院初仅设4个专业。1984年&#xff0c;学校设12个系(26个专业)&#x…

Linux系统以源码方式安装软件的方法

以下内容源于网络资源的整理&#xff0c;如有侵权请告知删除。 Linux系统中安装软件的三种方法_馨若梦的博客-CSDN博客_linux怎么安装软件 Linux下源码编译安装详解_Zebul博的博客-CSDN博客_编译安装 Linux源码包的一般安装步骤_Kaiattrib的博客-CSDN博客_linux源码包安装步…

hdu4565之矩阵快速幂

So Easy! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 813 Accepted Submission(s): 226 Problem Description A sequence S n is defined as: Where a, b, n, m are positive integers.┌x┐is the ceil …

Red Hat Enterprise Linux Server release 7.0双系统安装

2019独角兽企业重金招聘Python工程师标准>>> Red Hat Enterprise Linux Server release 7.0双系统安装 1.RedHat 公司的企业版7.0已经发布了。下面介绍一下在7.0下装双系统的步骤。 安装前系统&#xff1a;WIN7 要安装的第二个系统:RedHat Enterprise 7.0 请注意&am…

Android的按钮单击事件及监听器的实现方式

2019独角兽企业重金招聘Python工程师标准>>> 第一种&#xff1a;匿名内部类作为事件监听器类 大部分时候&#xff0c;事件处理器都没有什么利用价值&#xff08;可利用代码通常都被抽象成了业务逻辑方法&#xff09;&#xff0c;因此大部分事件监听器只是临时使用一…

Sublime text在Linux下的安装与配置

以下内容源于网络资源的整理&#xff0c;如有侵权请告知删除。文章内容主要整理源&#xff1a;C语言中文网&#xff1a;C语言程序设计门户网站(入门教程、编程软件)。 一、安装Sublime text 安装方法有两种&#xff1a;利用软件包管理工具安装&#xff0c;利用下载好的软件包进…

在Spring中使用JTA事务管理

2019独角兽企业重金招聘Python工程师标准>>> Spring 通过AOP技术可以让我们在脱离EJB的情况下享受声明式事务的丰盛大餐&#xff0c;脱离Java EE应用服务器使用声明式事务的道路已经畅通无阻。但是很大部分人都还认为脱离Java EE应用服务器就无法使用JTA事务&#x…

第一季7:海思的根文件系统的概览与制作

一、根文件系统理论 关于根文件系统的原理&#xff0c;可以参看以下博客。 根文件系统的原理 使用BusyBox制作根文件系统的理论分析 二、海思的根文件系统 1、海思的根文件系统体现在Hi3518E_SDK_V1.0.3.0\package\rootfs_uclibc目录。 而根文件系统大部分工作由etc/init.d/…

第一季8:完整版(即包含mpp)根文件系统的制作

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、概述 mpp是海思编写的与视频编解码有关的驱动、库等内容。我们需要部署这些内容&#xff0c;也就是把这些内容放在合适的目录位置。 二、mpp的目录结构 mpp目录位于Hi3518E_SDK_V1.0.3.0\pack…

计算机三级会保研加分吗,366所高校有保研资格,除了对成绩有要求外,还有哪些要求?...

文&#xff5c;冷丝栏目&#xff5c;考研录取我国本科院校有1000余所&#xff0c;具有保研资格的高校有366所&#xff0c;这些高校也是在不同年份按照不同批次获得保研资格。(本文文末附录全部高校名单)推免制度最初的目的上为了提高招生工作的质量&#xff0c;并且加大培养拔尖…

第一季8:sample_venc.c的编译和测试

注意&#xff0c;以下内容基于前面完整版的根文件系统&#xff0c;因此需要先完成前面的步骤。 1、明确sample文件夹的位置 海思SDK有很多sample&#xff0c;以方便开发人员的参阅。sample文件夹位于/package/mpp/目录下。 其中/package/mpp/sample/venc目录完成了视频的采集以…

计算机电缆 耐火,耐火计算机电缆ZR-NH-DJVVP

耐火计算机电缆ZR-NH-DJVVP低烟无卤阻燃计算机电缆用途&#xff1a;本电缆具有低压电容和低电感&#xff0c;并具有良好屏蔽性能和抗干扰性能&#xff0c;因而防爆性能优于一般计算机电缆和控制电缆&#xff0e;它适用于有防爆要求场合的集散系统和自动化检测控制等要求低烟无卤…