当前位置:首页 » 编程语言 » c语言和内存

c语言和内存

发布时间: 2025-07-29 08:13:03

A. C语言:关于动态内存的复习总结(分配器)

C语言中动态内存管理是程序员必须掌握的重要知识点,主要涉及内存的三个区域:栈区、堆区和数据区。其中,栈区主要存放局部变量,函数调用结束后自动释放;堆区由malloc或new动态分配,需要程序员手动释放,未释放的内存会持续存在直到程序结束;数据区则包含全局变量和静态变量,其生命周期与程序同进退。

在内存操作中,常见的问题包括:未给指针分配合法内存、分配空间不足、未初始化、指针越界和内存泄漏。动态内存分配器如malloc和free,维护进程的虚拟内存堆,分为显示分配器(如C语言)和隐式分配器(如垃圾收集器)两种模式,前者需要显式释放,后者负责自动回收不再使用的内存。

动态内存分配的目标是满足程序运行时对内存大小的不确定性,避免空间浪费或不足。分配器需要满足一系列要求,如处理任意请求、不修改已分配内存、只在堆区分配等,以最大化吞吐率和内存利用率。实现动态内存分配器时,会面临空闲块组织、放置策略和内存合并等问题,如隐式空闲链表就通过头尾信息来连接空闲块,虽然简单但搜索效率低。

显示空闲链表则是将空闲内存块组成一个独立的链表,相比隐式链表,它在首次适配时的时间复杂度更低,释放和合并操作也有特定的优势。掌握这些概念和操作,可以帮助程序员更好地管理内存,提高代码的健壮性和效率。

B. C语言 + 单片机-内存分布详解

C语言内存分区示意图如下:

1. 代码区

2. 常量区

3. 全局(静态)区

.bss段

.data段

4. 堆区(heap)

调用函数参数size_t是分配的字节大小,返回值是一个void型的指针,该指针指向分配空间的首地址。参数是开辟的内存的首地址。

5. 栈区(stack)

在STM32中,内存分配如下:

1. 随机存储器—RAM

2. 只读存储器—ROM

STM32F103芯片的内部分区如下图所示。

编译程序完成后,可以看到编译后的大小信息,包括Code、RO-data、RW-data和ZI-data的大小。这有助于开发人员和嵌入式系统设计者更好地管理内存资源并确保程序在目标设备上正常运行。

Code:代码段,指程序由编译器生成的可执行的机器指令。

RO-data:数据段,指程序中的只读数据部分,包括常量、字符串、const定义的变量等。

RW-data:数据段,指初始化为“非0值“的可读写数据,程序运行的时候这些数据又会常驻在RAM区,应用程序可以修改其内容。包括初始化为非零的全局变量和静态变量。

ZI-data:数据段,指初始化为0值的可读可写数据,它与RW-data的区别是程序刚运行时这些数据初始值全都为0,程序运行时和RW-data的性质一样,它们也常驻在RAM区,应用程序可以更改其内容。包括未初始化和初始化为零的全局变量和静态变量。

ZI-data 的栈空间(Stack)及堆空间(Heap):在C语言中,函数内部定义的局部变量属于栈空间,而使用malloc动态分配的变量属于堆空间。在程序中的栈空间和堆空间都是属于ZI-data区域的,这些空间都会被初始值化为0值。

关于哪些数据存储在Flash区域,哪些数据存储在SRAM区域,这涉及到程序的存储状态。程序具有静止和运行两种状态,静止态的程序被存储在非易失存储器中,如内部FLASH区域。当程序在运行状态的时候,程序常常需要修改一些暂存数据,这些数据往往存放在Flash中,但需要被复制到RAM中。

程序存储分布如下图展示。当程序存储到芯片的内部FLASH时,它占用的空间为Code+RO-data+RW-data的总和。程序在执行的时候,需要占用内部SRAM空间,占用的空间为RW-data+ZI-data之和。

结论,想要让一个程序正常运行,必须满足以下两个条件:程序编译后打开工程的map文件,在map文件的最后一段也可以看到ROM的总大小。

划分依据及好处:首先区分代码段和数据段。程序源代码编译后的机器指令放在代码段;数据段包括" .data "、" .bss "、" .rodata ",将程序中定义的全局变量和局部变量都称为数据段。

把程序的“代码段”和“数据段”分开存放,数据和指令分别被映射到两个虚拟内存区域,数据段对进程是可读写的,而代码段对进程是只读的。现代CPU缓存设计成数据缓存和指令缓存分离,程序的指令和数据分开存放提高缓存命中率。

数据段还需要分 ".data"、".bss"、".rodata",主要根据是否占内存空间、读写权限进行区分。".data"段和".bss"段都是可读写的数据段,而".rodata"存放的是只读数据,主要是一些const变量和字符串常量。".rodata"段单独设立的好处是可以将属性映射成只读,减少修改操作,还可以将".rodata"段存放在只读存储器中。

全局变量也有细分初始化和未初始化,把全局变量分开存放,初始化为0和未初始化的全局变量放在BSS区,初始化不为0的全局变量存放在数据区。程序有两个存储状态,静止状态的程序被存储在非易失存储器中,运行状态的程序需要修改一些暂存数据存放在内存中,减少从ROM读数据的次数提高效率。

C. 详细讲解C语言五大内存分区与可执行程序的三段(Text段、Date段、Bss段)【建议收藏】

本文详细讲解C语言五大内存分区与可执行程序的三段(Text段、Data段、Bss段)。
首先,C语言五大内存分区包括:静态内存、动态内存、栈内存、堆内存和文件I/O内存。静态内存用于存储全局变量和静态变量,动态内存由new和malloc函数分配,栈内存用于函数调用时的局部变量和函数参数,堆内存用于动态分配和管理,文件I/O内存用于文件读写操作。
其次,可执行程序的三段分别为:Text段、Data段、Bss段。Text段存储了程序的机器代码,Data段存储了程序的全局变量和静态变量的初始值,Bss段用于存放未初始化的全局变量和静态变量。Text段和Data段是只读的,而Bss段是可读可写的。
在可执行程序内存空间与逻辑地址空间的映射与划分上,执行文件通常被映射到进程的逻辑地址空间中。执行文件的文本、数据和Bss段分别映射到进程的文本、数据和Bss段。
接着,存储类型关键字定义了变量的存储类型,如static、extern、auto和register。这影响了变量的作用域和生命周期。静态变量在全局或文件级作用域中,其生命周期在程序运行期间一直存在;外部变量在文件级作用域中,其值在程序运行期间始终存在;自动变量在函数作用域中,其值在函数调用结束后释放;寄存器变量在函数调用期间使用,以提高执行效率。
在堆与栈的区别上,堆和栈在申请方式、申请后的系统响应、申请大小限制、申请效率、存储内容以及存取效率上有所不同。在运行时刻赋值的变量通常在堆中分配,而编译时已经确定的变量通常在栈中分配。在存取效率上,栈上的数组比指针指向的字符串更快。

热点内容
实数与复数的运算法则 发布:2025-07-29 17:13:19 浏览:487
qq辅助源码 发布:2025-07-29 17:03:39 浏览:864
sqlite创建数据库 发布:2025-07-29 16:57:20 浏览:220
最新百度算法 发布:2025-07-29 16:52:19 浏览:214
求游戏源码 发布:2025-07-29 16:46:33 浏览:464
样品制备区配置什么设备 发布:2025-07-29 16:44:57 浏览:672
为什么mc服务器会被清除 发布:2025-07-29 16:44:12 浏览:725
手机配置不好的如何开最高画质 发布:2025-07-29 16:39:20 浏览:569
脚本灵感 发布:2025-07-29 16:39:07 浏览:99
网页紧急升级访问通知 发布:2025-07-29 16:39:04 浏览:46