当前位置:首页 > 芯闻号 > 充电吧
[导读]最近很多同学希望了解C语言的内存分配,虽然可以在互联网上找到诸多的讲解,但是你会发现要么不通俗易懂,要么不算太全面。而这些对于新手而言,又绝对会把你弄得晕头转向的,所以在此对网上和书本上的诸般讲解,进


最近很多同学希望了解C语言的内存分配,虽然可以在互联网上找到诸多的讲解,但是你会发现要么不通俗易懂,要么不算太全面。而这些对于新手而言,又绝对会把你弄得晕头转向的,所以在此对网上和书本上的诸般讲解,进行了通俗的翻译和总结。

在说内存分配之前,先提一点题外话,因为在和同学们讲解内存分配的时候,他们不是很明白为什么要进行这样的分配。所以先讲解下,计算机的组成和基本原理。

一、计算机的组成

计算机的五大组成部分:运算器、控制器、存储器、输入设备和输出设备。

我们都知道计算机的处理中心是CPU,它主要由运算器和控制器组成。

1) 运算器

实现算术运算和逻辑运算的部分,主要对数据进行加工处理。

2) 控制器

计算机的指挥中心,它通过地址访问存储器,从存储器中取出指令(程序),并指出下一指令在存储器中的位置,将取出的指令经指令寄存器送往指令译码器,经过对指令的分析产生相应的操作,控制其他部件的有条不紊的工作。

执行指令有四个步骤:取指令、指令译码、按指令操作码执行、形成下一条指令地址。

3)存储器

计算机存放所有数据和程序的记忆部分,它分为两大类:一类是内部存储器(内存),一类是外部存储器(外存)。存储器由若干个存储单元组成,每个存储单元都有一个地址,计算机通过地址对存储单元进行读写。

4) 输入设备

向计算机输入信息(程序、数据、声音、文字、图形、图像等)的设备(键盘、鼠标、图形扫描仪、触摸屏、条形码输入器、光笔等)。

5) 输出设备

主要有显示器、打印机和绘图仪等。

二、内存分配

在任何程序设计环境及语言中,内存管理都十分重要。在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的。因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题

1) C程序结构:可执行代码存储时

下面是C语言可执行程序的基本情况:



上面分别是:代码区、全局初始化数据区/静态数据区、未初始化数据区、十进制总和、十六进制总和、文件名。

我们可以看出程序在未运行前,没有调入到内存时,分为三个部分:代码区(text)、数据区(data)、未初始化数据区(bss)。

(1) 代码区(text)

存放CPU可执行的机器指令,由于程序被经常使用,防止其被意外修改,代码区通常是只读的。

(2) 全局初始化数据区/静态数据区(data)

存放被初始化的全局变量、静态变量(全局静态变量和局部静态变量)、常量数据(如字符串常量)。

(3) 未初始化数据区(BSS)

存放未初始化的全局变量,BSS这个叫法是根据早期的汇编运算符而来的,这个汇编运算符标志着一个块的开始。BSS区的数据在程序开始执行之前被内核初始化为0或空指针(NULL)。

2)C程序结构:程序执行时

一个正在运行的C程序,占用的内存分为5个区域:代码区、初始化数据区/静态数据区、未初始化数据区、堆区、栈区。

(1) 代码区(text)

代码区指令根据程序设计流程依次执行,对于顺序指令,则只会执行一次,如果反复,则需使用跳转指令,如果进行递归,则需借助栈来实现。

代码区包括操作码和要操作的对象(或对象的地址引用),如果是立即数(即具体的数值,如2),将直接包含在代码中;如果是局部数据,将在栈中分配空间,然后引用该数据的地址;如果是BSS区和数据区,在代码中同样引用该数据的地址。

(2) 全局初始化数据区/静态数据区(data)

只初始化一次。上面已经说过,在程序编译时,该区域已经被分配好了,这块内存在程序的整个运行期间都存在,当程序结束时,才会被释放。

(3)未初始化数据 区(BSS)

在运行时改变其值。

(4)栈区(stack)

存放函数的参数值和局部变量,由编译器自动分配释放,其操作方式类似于数据结构的栈。其特点是不需要程序员去考虑内存管理的问题,很方便;同时栈的容量很有限,在Linux系统中,栈的容量只有8M,并且当相应的范围结束时(如函数),局部变量就不能再使用。

(5)堆区(heap)

有些操作对象只有在程序运行时才能确定,这样编译器在编译时就无法为他们预先分配空间,只有程序运行时才分配,这就是动态内存分配。堆区就是用于动态内存分配(如malloc的动态内存分配),堆在内存中位于bss区和栈区之间,一般由程序员申请和释放。

之所以分配如此多的区域,主要是因为:

一个进程在运行时,代码是根据流程依次执行的,代码只需访问一次,当然跳转或递归时代码会被执行多次,而数据一般都需要访问多次,因此单独开辟空间以便访问和节约空间。

下面是一个详细的代码,来全面分析内存分配情况:

//main.c

int a = 0; //a在全局初始化数据区

char *p1; //p1在bss区(未初始化全局变量)

static int c = 0; //c在全局初始化数据区(c是全局静态变量)

struct employee

{

char name[20];

int age;

float score;

}e1; //e1在全局初始化数据区

int main()

{

int b; //b在栈区(局部变量)

char s[] = “abc”; //s在栈区,“abc”在常量区(全局初始化数据区)

char *p2; //p2在栈区

char *p3 = “123456”; //p3在栈区,“123456”在常量区(全局初始化数据区)

static int d = 0; //d在全局初始化数据区(静态局部变量)

struct student

{

char *name; //name在栈区,name指针指向是在堆区

int age;

float score;

}s1; //s1在栈区

p1 = (char*)malloc(10); //分配得来的10个字节的区域在堆区

p2 = (char*)malloc(20); //分配得来的20个字节的区域在堆区

name = (cahr *)malloc(20); //分配得来的20个字节的区域在堆区

/*从常量区的“Hello World”字符串复制到刚分配到的堆区*/

strcpy(p1, “Hello World”);

free(p1); //释放内存

free(p2); //释放内存

}


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭