C 语言内存分配


640?wx_fmt=jpeg

640?wx_fmt=jpeg

昨天有一个群里的同学问我,他问我的问题是 c 语言函数是存在哪里的?是如何执行的?我下意识的觉得这位同学应该是个初学者,所以今天就写下一些基础方面的内容,「C语言的内存布局」。


程序代码可以看做是一个人,是人就需要有房子住,操作系统就是政府,政府有义务给找个位置给你住,如果你是高级人才,他就给你个 vip ,给你分个大房子,但是如果你对社会没有帮助(  手上没钱),那你可能就需要住天桥下。


我们刚开始学习单片机的时候,还没有进程,线程,操作系统的概念,程序直接下载到 rom 里面,等你有了操作系统概念,反过来看看,会觉得以前自己写的代码都是单线程的。

2

C 语言内存分配的框图如下,一个正常的执行代码, 操作系统需要给他分配一段内存区域,这一大块内存区域还要分为几个小区域。


1.文本段(Text segment
2.初始化数据段(Initialized data segment
3.未初始化数据段(Uninitialized data segment
4.堆栈(Stack
5.堆 (Heap

640?wx_fmt=png


3

1.文本段:
文本段,也称为代码段,是目标文件或内存中包含可执行指令的程序的一部分。

作为存储区域,文本段可以放置在堆或堆栈下方,以防止堆和堆栈溢出覆盖它。

通常,文本段是可共享的,因此对于频繁执行的程序(例如文本编辑器,C 编译器,shell 等),只需要一个副本就可以在内存中。此外,文本段通常是只读的,以防止程序意外修改其指令。


文本段可以看做 这段代码 的 大脑,需要怎么执行,做什么,都把数据保存在这个位置了。


2.初始化数据段:
初始化数据段,通常简称为数据段。数据段是程序的虚拟地址空间的一部分,其包含由程序员初始化的全局变量和静态变量。

请注意,数据段不是只读的,因为变量的值可以在运行时更改。

该段可以进一步分类为初始化的只读区域初始化的读写区域

例如,C 中的 char s [] =“hello world”定义的全局字符串,和 int debug = 1 之类的 C语句 将存储在初始化的读写区域中。像 const char * string =“hello world”这样的全局 C语句 会把 字符串文字“hello world”存储在初始化的只读区域中,而字符指针变量字符串存储在初始化的读写区域中。

例如:static int i = 10 将存储在数据段中,global int i = 10 也将存储在数据段中

3.未初始化的数据段:

未初始化的数据段,通常称为“bss”段,以古代汇编运算符命名,代表“由符号启动的块”。此段中的数据在程序启动之前由内核初始化为算术 0 执行

未初始化的数据从数据段的末尾开始,包含初始化为零或在源代码中没有显式初始化的所有全局变量和静态变量

例如,变量声明为static int i; 将包含在BSS部分中。
例如,一个声明为int j的全局变量; 将包含在BSS部分中。

4.堆栈:

我们很多时候说的堆栈,实际上就是栈( stack )跟堆( heap )是没有关系的。我们学习上经常说的 压栈,说的就是压堆栈,因为堆栈有 「先进后出的原则」,所以我们操作的是栈尾。

堆栈区域传统上与堆区域相邻并向相反方向增长; 当堆栈指针遇到堆指针时,可用内存耗尽(因为理论上这个两个家伙是不可能 相遇的) 。(使用现代大地址空间和虚拟内存技术,它们几乎可以放置在任何地方,但它们通常仍会朝着相反的方向发展。)

堆栈区域包含程序堆栈,LIFO结构,通常位于存储器的较高部分。在标准的PC x86计算机体系结构上,它向零地址发展; 在其他一些架构上,它朝着相反的方向发展。“堆栈指针”寄存器跟踪堆栈的顶部; 每次将值“推”到堆栈上时都会调整它。

5.堆:
堆是通常发生动态内存分配的段。

堆区域从BSS 段的末尾开始,并从那里增长到更大的地址。堆区域由 malloc,realloc 和 free 管理,可以使用 brk 和 sbrk 系统调用来调整其大小;它们也可以使用mmap实现,将不连续的虚拟内存区域保留到进程的“虚拟地址空间”中。堆区域由进程中的所有共享库和动态加载的模块共享。

4

实用 size 命令可以分析生成的可执行程序每个段的大小,单位是(bytes 字节)。我们可以用这个命令验证上面的论证。

代码实例

#include<stdio.h>

int main()
{
    return 0;
}
Linux@dev:~/cStudy$ gcc memory-test.c -o memory-test && size memory-test
   text    data     bss     dec     hex filename
   1099     544       8    1651     673 memory-test
Linux@dev:~/cStudy

现在代码里面什么都没有,可以看到每个段内容的大小。

#include<stdio.h>

int g;

int main()
{
    static int i;
    return 0;
}
--------------------------------------------------
Linux@dev:~/cStudy$ gcc memory-test.c -o memory-test && size memory-test
   text    data     bss     dec     hex filename
   1099     544      16    1659     67b memory-test
Linux@dev:~/cStudy

我们声明了一个未初始化的全局变量和一个未初始化的静态变量后,bss 段发生了变化。


再修改一下

#include<stdio.h>

int g = 99;

int main()
{
    static int i = 100;
    return 0;
}
--------------------------------------------------
Linux@dev:~/cStudy$ gcc memory-test.c -o memory-test && size memory-test
   text    data     bss     dec     hex filename
   1099     552      8     1659     67b memory-test
Linux@dev:~/cStudy

初始化后 bss 段变成原来 8 了, data 段多了 8 个字节。

再修改一下

#include<stdio.h>

int g ;

int main()
{
    static int i = 100;
    return 0;
}
--------------------------------------------------
Linux@dev:~/cStudy$ gcc memory-test.c -o memory-test && size memory-test
   text    data     bss     dec     hex filename
   1099     548      12     1659     67b memory-test
Linux@dev:~/cStudy

这样 bss 段和 data 段都比初始值增加了 4 个字节。

5

推荐之前跟这个相关的文章,也是写 内存 区域的东西,两篇文章联系起来看会非常好。

堆和栈的区别(转过无数次的文章)


还是推荐一下我的知识星球,加入星球的福利我会慢慢增加,当然还是以自愿为主,加入星球了同学,希望还是在星球提问题,这样的问答环境会更好,也方便追溯问题。

我的知识小密圈


昨天大概看了一下文章的情况,发现收藏的人数很多,但是转发的人数很少,各位大哥哥,大帅哥,能不能给小弟一点点活路稍微转发一下,在知乎的时候,就是收藏的数量远远超过点赞,已经让我很伤心了。


完,各位共勉~


640?wx_fmt=gif

640?wx_fmt=jpeg


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

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

相关文章

正则表达式符号特殊详解_常用正则表达式_Java中正则表达式的使用

正则表达式符号详解 限定符: 指定一个组件必须出现多少次才能满足. 1.使用 “*”, “”, “?” 作为限定符: "*": 匹配前面的子表达式零次或多次。例如&#xff0c;zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。"": 匹配前面的子表达…

python中求包含5的数_Python 内置函数 ( ) 可以返回列表、元组、字典、集合、字符串以及 range 对象中元素个数。_学小易找答案...

【简答题】实例1:求两数相除的结果。 先后输入2个数据,计算第一个数除以第二个数的结果。 要求能够处理输入数据为非数字、除数为零、文件末尾EndOfFile 和用户使用Ctrl + C 命令终止程序等异常,提高用户体验。 当输入数据为非数字时提示错误信息并让用户重新输入。 input()函数…

没有梦想,你跟咸鱼有什么分别?

&#xff11;标题起的有点夸张&#xff0c;其实这个就是一个招聘贴&#xff0c;之前从来没有用发头条文章来招聘&#xff0c;实在不好意思&#xff0c;这个招聘对我非常重要&#xff0c;这是一个非常好的朋友公司的招聘信息&#xff0c;也希望大家帮忙扩散一下&#xff0c;因为…

一个很Low的通讯录管理系统(但是能用)C/C++单链表实现

通讯录管理系统的设计 问题需求分析 在计算机还未普及之前通讯管理都是由联系人采用名片&#xff0c;通讯录往往采用的是笔录手工记帐的方式来操作的。现在一般的通讯录管理都是采用计算机作为工具的实用的计算机通讯录管理程序来帮助人们进行更有效的通讯录信息管理。本通讯…

2017《面向对象程序设计》课程作业三

作业链接github链接 对于文件读写和多参数主函数学习过程中遇到的问题 这次文件读写改用了C的形式&#xff0c;然后总体还算顺利&#xff0c;借鉴了林燊的&#xff0c;因为他写的代码最容易看懂&#xff1b;还有就是借鉴了《C程序设计》&#xff0c;讲真&#xff0c;谭浩强的还…

做人力资源需要掌握python_9种人力资源分析工具,高效打造数字化HR全流程

对于许多人和组织而言&#xff0c;采用HR分析是一大进步。确实&#xff0c;我经常被问到&#xff1a;“最好使用什么人力资源分析工具&#xff1f;”本文将为您提供该问题的答案&#xff0c;以下是要使用的九种最佳人力资源分析工具的列表。1、RR是最常用的HR分析工具。R非常适…

华为不做黑寡妇,开源编译器,与友商共建安卓性能

&#xff11;今天我的一个老哥开了头条号&#xff0c;第一次发文章&#xff0c;我觉得不错&#xff0c;拿来用用&#xff0c;给大家看看华为技术总工的文采。这位总工潜伏在我的微信群里很少说话&#xff0c;大家一定要有这个想法&#xff0c;就是最低调的那个人&#xff0c;真…

点击链接如何直接跳转到相对应的聊天窗口

解决这个问题的步骤如下&#xff1a; <a target"_blank" href"http://wpa.qq.com/msgrd?v3&uin3237465337&siteqq&menuyes">一、登陆腾讯官方网站&#xff1a;http://wp.qq.com/ 二、登陆之后&#xff0c;点“设置”&#xff0c;按下图…

哈夫曼树编码与译码(完整C/C++实现代码)

哈夫曼编码的设计与应用 问题需求分析 用哈夫曼编码(Huffman Coding)&#xff0c;又称霍夫曼编码&#xff0c;是一种编码方式&#xff0c;哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法&#xff0c;该方法完全依据字符出现概率来构造异字头的平均长…

移动应用开发实例_物联网改变移动应用开发的4种方式

图片来源&#xff1a;pixabay.com来源&#xff1a;物联之家网(iothome.com)转载请注明来源&#xff01;物联网改变了移动应用程序的开发格局。那么&#xff0c;为物联网开发移动应用程序有何不同&#xff1f;物联网与移动应用程序开发齐头并进。物联网改变了人类与机器的互动方…

谁都能看懂的网络模型知识

&#xff11;.网络是我们做嵌入式 避无可避的知识点&#xff0c;但是网络的层次很多&#xff0c;很多时候我们根本理解不了其中的层次和作用&#xff0c;今天跟我们公司的 X 总聊到这个&#xff0c;给我普及了一些知识&#xff0c;我觉得非常有用&#xff0c;分享给大家。最近事…

Java微信公众平台获取签名

如果想使用微信的JSSDK&#xff0c;需要注册公众号和获取签名&#xff0c;Java代码实现如附件&#xff1a; 使用的是servlet&#xff0c;access_token和ticket缓存在application作用域里 附件为源代码&#xff1a;wx.zip转载于:https://www.cnblogs.com/yrcn/p/6831808.html

常用排序算法以及算法性能测试(完整C/C++代码实现)

排序算法性能的比较 注: 由于只是测试算法性能, 所以不会对排序算法做深入讲解, 在随后的时间将会推出排序的详细讲解 问题需求分析 排序算法经过了很长时间的演变&#xff0c;产生了很多种不同的方法。每种算法主要针对不同的数列进行排序&#xff0c;这些排序算法具有各自…

jquery点击事件传值加载页面_jQuery添加options点击事件并传值

var formStr "{supplierId:供应链企业|%-jm-sprt-%|93794498-3}";$.ajax({type : "post",dataType : "json",cache : false,url : "../../../webservice/gmall.json", // 提交到一般处理程序请求数据data :"businessCode6100100…

我就随便BB一下

&#xff11;.如果我开始写文章的时候&#xff0c;停顿了几分钟&#xff0c;那结果应该很明显&#xff0c;这一定是一篇比较垃圾的文章&#xff0c;没什么东西值得看&#xff0c;所以我把之前的删除了&#xff0c;重新开头来写&#xff0c;我认为&#xff0c;一个好的开头一定是…

JS代码优化工具Prepack

最近&#xff0c;Facebook 发布 Prepack :一个优化 JavaScript 源代码的工具&#xff0c;实际上它是一个 JavaScript 部分求值器(Partvaluator)&#xff0c;可在编译时执行原本在运行时的计算过程&#xff0c;并通过重写 JavaScript 代码来提高其执行效率。(西安尚学堂&#xf…

读Java并发编程实践记录_原子性_锁_同步容器详解_任务执行

原子性: 单独的,不可分割的操作 不要使用过期状态值来决策当下的状态, 一定要先检查再执行(不检查, 将引发数据修改,丢失)避免延迟初始化(懒加载: 先查看对象 null, 然后new), 有可能查看对象状态的时候, 对象已经new出来, 只不过还没将对象赋给引用避免复合操作, 例: count;…

和我一起探索嵌入式

&#xff11;.本文为微信群管理员小磊投稿作品&#xff0c;作者计划编写一系列文章&#xff0c;该篇为第一篇&#xff0c;如果有做STM32的同学这将是一个非常好的系列教程&#xff0c;欢迎关注。我15年刚建立了一个BLE的QQ群&#xff0c;很有幸认识了小磊同学&#xff0c;一个非…

经纬度坐标系转东北天_大地坐标系(WGS-84)、地心地固坐标系(ECEF)与东北天坐标系(ENU)的相互转换C语言代码分享...

//ECEF ---> WGS84//pcg为WGS-84坐标系结构体指针&#xff0c;pcc为ECEF坐标系结构体指针void ECEFToWGS(PWGS pcg, PECEF pcc){double B0, R, N;double B_, L_;double X pcc->x;double Y pcc->y;double Z pcc->z;R sqrt(X * X Y * Y);B0 atan2(Z, R);while …

2.简易的登录页面(表单验证)(HTML+JavaScript+Jquery)

//HTML部分 <!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title>登录页面</title> <link rel"stylesheet" type"text/css" href"css/login.css"/> <s…