【C语言天天练(二四)】内存分配

【C语言天天练(二四)】内存分配

大家好,又见面了,我是全栈君。

引言:

      

        对于C语言程序,了解它执行时在内存中是怎样分配的对于我们理解它的执行机制是很实用的。以下就总结一下C语言程序的一些内存分配知识。


        一段C程序。编译连接后形成的可运行文件一般有代码段、数据段、堆和栈等几部分组成。当中数据段又包含仅仅读数据段、已初始化的读写数据段和未初始化的BSS段。例如以下图所看到的:

【C语言天天练(二四)】内存分配

文本段:存放程序运行的代码。


数据段:

1>仅仅读数据段:

仅仅读数据段是程序使用的一些不会被更改的数据,使用这些数据的方式类似查表式的操作,因为这些变量不须要更改,因此仅仅须要放置在仅仅读存储器中就可以。

通常是const修饰的变量以及程序中使用的文字常量通常会存放在仅仅读数据段中。

2>已初始化的读写数据段:

已初始化数据是在程序中声明,而且具有初值的变量。这些变量须要占用存储器的空间,在程序执行时它们须要位于可读写的内存区域内。而且有初值,以供程序执行时读写。在程序中一般为已经初始化的全局变量,已经初始化的静态局部变量(static修饰的已经初始化的变量)

3>未初始化段(BSS):

未初始化数据是在程序中声明,可是没有初始化的变量,这些变量在程序执行之前不须要占用存储器的空间。

与读写数据段类似,它也属于静态数据区。

可是该段中数据没有经过初始化。

未初始化数据段仅仅有在执行的初始化阶段才会产生,因此它的大小不会影响目标文件的大小。在程序中通常是没有初始化的全局变量和没有初始化的静态局部变量。


堆:需程序猿自己申请(调用malloc,realloc,calloc),并指明大小,并由程序猿进行释放。


栈:由系统自己主动分配。比如,声明在函数中一个局部变量int b;系统自己主动在栈中为b开辟空间。


依据上面的理论知识,分析演示样例片段的内存分配:

【C语言天天练(二四)】内存分配


栈与堆的差别:

1.申请方式

(1)栈(satck):由系统自己主动分配。比如,声明在函数中一个局部变量int b;系统自己主动在栈中为b开辟空间。

(2)堆(heap):需程序猿自己申请(调用malloc,realloc,calloc),并指明大小,并由程序猿进行释放。

easy产生memory leak.

eg:char  p;

      p = (char *)malloc(sizeof(char));

可是,p本身是在栈中。

2.申请大小的限制

(1)栈:栈是向底地址扩展的数据结构,是一块连续的内存区域(它的生长方向与内存的生长方向相反)。栈的大小是固定的。假设申请的空间超过栈的剩余空间时,将提示overflow。

(2)堆:堆是高地址扩展的数据结构(它的生长方向与内存的生长方向同样)。是不连续的内存区域。这是因为系统使用链表来存储空暇内存地址的。自然是不连续的,而链表的遍历方向是由底地址向高地址。

堆的大小受限于计算机系统中有效的虚拟内存。

3.系统响应:

(1)栈:仅仅要栈的空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

(2)堆:首先应该知道操作系统有一个记录空暇内存地址的链表,但系统收到程序的申请时,会遍历该链表。寻找第一个空间大于所申请空间的堆结点。然后将该结点从空暇链表中删除。并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小。这样。代码中的free语句才干正确的释放本内存空间。另外。找到的堆结点的大小不一定正好等于申请的大小,系统会自己主动的将多余的那部分又一次放入空暇链表中。

说明:对于堆来讲,频繁的malloc/free势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率减少。对于栈来讲。则不会存在这个问题,

4.申请效率

(1)栈由系统自己主动分配,速度快。但程序猿是无法控制的

(2)堆是由malloc分配的内存,一般速度比較慢,并且easy产生碎片。只是用起来最方便。

5.堆和栈中的存储内容

(1)栈:在函数调用时,第一个进栈的主函数中后的下一条语句的地址。然后是函数的各个參数,參数是从右往左入栈的,然后是函数中的局部变量。注:静态变量是不入栈的。

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

(2)堆:通常是在堆的头部用一个字节存放堆的大小。

6.存取效率

(1)堆:char *s1=”hellow tigerjibo”;是在编译是就确定的

(2)栈:char s1[]=”hellow tigerjibo”;是在执行时赋值的;用数组比用指针速度更快一些,指针在底层汇编中须要用edx寄存器中转一下,而数组在栈上读取。

补充:

栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令运行。这就决定了栈的效率比較高。

堆则是C/C++函数库提供的,它的机制是非常复杂的,比如为了分配一块内存。库函数会依照一定的算法(详细的算法能够參考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,假设没有足够大小的空间(可能是因为内存碎片太多)。就有可能调用系统功能去添加程序数据段的内存空间。这样就有机会分到足够大小的内存,然后进行返回。显然。堆的效率比栈要低得多。

7.分配方式:

(1)堆都是动态分配的,没有静态分配的堆。

(2)栈有两种分配方式:静态分配和动态分配。静态分配是编译器完毕的。比方局部变量的分配。

动态分配由alloca函数进行分配,可是栈的动态分配和堆是不同的。

它的动态分配是由编译器进行释放,无需手工实现。

參考1:http://blog.csdn.net/tigerjibo/article/details/7423728

參考2:http://blog.csdn.net/to_be_it_1/article/details/31420549

參考3:http://blog.csdn.net/lovecodeless/article/details/24384093

參考4:http://blog.csdn.net/lovecodeless/article/details/21084513

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116396.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 海洋测绘 知识点 详细

    海洋测绘 知识点 详细一、第一章海洋测绘概述第一节、海洋测绘的发展第二节、世界海洋新格局1.海洋法公约的一些主要概念与定义:(1)内海:也叫内水,指的是领海基线以内的水域,国家对其享有完全排他性主权(2)领海:领海向外延伸12海里的区域(1海里(nmi)=1.852千米(km),沿海国主权管辖下与其海岸或内水相邻的一定宽度的海域,是国家领土的组成部分(3)毗邻区:毗邻国家领海,并在领海外一定宽度的,供沿…

    2022年6月6日
    60
  • mysql自定义函数详解_sql自定义函数例子

    mysql自定义函数详解_sql自定义函数例子摘要腾兴网为您分享:mysql自定义函数与动态查询,智学网,夜读小说,小睡眠,西餐菜谱等软件知识,以及猫语翻译器,江西校讯通,刷qq业务的网站,房洽洽,学士服照,爱站seo工具包,虚拟声卡驱动,隐藏分,卦象,供零在线永辉,七猫精品小说,海纳百川器,华尔街日报,双十一图片,中国地震信息网等软件it资讯,欢迎关注腾兴网。介绍下mysql自定义函数的例子,以及插入单引号的方法,动态执行查询与字符串拼接…

    2025年10月7日
    3
  • 深入理解java的finalize

    深入理解java的finalize基本预备相关知识 nbsp 1java 的 GC 只负责内存相关的清理 所有其它资源的清理必须由程序员手工完成 要不然会引起资源泄露 有可能导致程序崩溃 nbsp 2 调用 GC 并不保证 GC 实际执行 nbsp 3finalize 抛出的未捕获异常只会导致该对象的 finalize 执行退出 nbsp 4 用户以自己调用对象的 finalize 方法 但是这种调用是正常的方法调用 和对象的销毁过程无关 nbsp 5JVM 保证

    2025年6月6日
    2
  • Redis主从复制原理

    Redis主从复制原理

    2021年4月10日
    281
  • siege压力测试软件,WEB压力测试工具Siege

    siege压力测试软件,WEB压力测试工具Siege介绍 Siege 是一个 http https 负载测试和基准测试工具 它旨在让 WEB 开发人员了解自己代码在压力测试中的执行性能 Siege 支持基本身份验证 Coockie HTTP HTTPS 和 FTP 协议 用户也可以通过配置来模拟访问服务器的并发用户数 是一款非常方便的压力测试工具 官方网址 http www joedog org 下载网址 http www joedog org pub si

    2025年8月8日
    3
  • matlab矩阵存为txt_matlab数据批量处理

    matlab矩阵存为txt_matlab数据批量处理fileID=fopen(‘Data.txt’);A=textscan(fileID,’%f%*f%*f%*f%f%f%f’);fclose(fileID);Matrix=cell2mat(A);textscan中,%*f表示不读取该列数据。

    2025年9月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号