图解Linux下C内存分配 by using gpt

我们可以通过GPT来详细地图解Linux上的C内存分配。这个过程可以进一步细化,只要你愿意。

最小的 C 代码示例

以下代码使用了标准 C 库函数 malloc 分配一块内存:

#include <stdlib.h>
#include <stdio.h>int main() {int *ptr = (int *)malloc(sizeof(int) * 10); // 分配10个整数大小的内存if (ptr == NULL) {perror("Memory allocation failed");return 1;}free(ptr); // 释放内存return 0;
}

系统调用的分叉情况

brk 和 sbrk 系统调用接口

brksbrk 是用于调整数据段(heap)大小的系统调用。以下是它们的接口说明:

brk

#include <unistd.h>int brk(void *end_data_segment);
  • end_data_segment: 指向新的数据段末尾的指针。
  • 返回值: 成功时返回 0,失败时返回 -1 并设置 errno。

sbrk

#include <unistd.h>void *sbrk(intptr_t increment);
  • increment: 增加或减少数据段大小的字节数。
  • 返回值: 成功时返回之前的程序 break 地址,失败时返回 (void *) -1 并设置 errno。

直接从 C 代码调用 brk 和 sbrk 的示例

#include <unistd.h>
#include <stdio.h>int main() {void *initial_brk = sbrk(0); // 获取当前的程序 break 地址printf("Initial program break: %p\n", initial_brk);// 增加数据段大小if (sbrk(1024) == (void *) -1) {perror("sbrk failed");return 1;}void *new_brk = sbrk(0); // 获取新的程序 break 地址printf("New program break: %p\n", new_brk);// 恢复原来的数据段大小if (brk(initial_brk) == -1) {perror("brk failed");return 1;}printf("Program break reset to: %p\n", sbrk(0));return 0;
}

mmap 系统调用接口

mmap 是用于映射文件或设备到内存的系统调用。以下是它的接口说明:

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
  • addr: 映射的起始地址,通常为 NULL 以让内核选择地址。
  • length: 映射的字节数。
  • prot: 内存保护标志,如 PROT_READPROT_WRITE 等。
  • flags: 映射选项,如 MAP_PRIVATEMAP_ANONYMOUS 等。
  • fd: 文件描述符,若使用匿名映射则为 -1。
  • offset: 文件映射的偏移量,通常为 0。
  • 返回值: 成功时返回映射区域的指针,失败时返回 MAP_FAILED 并设置 errno。

直接从 C 代码调用 mmap 的示例

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>int main() {size_t length = 4096; // 映射 4KB 内存void *addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);if (addr == MAP_FAILED) {perror("mmap failed");return 1;}printf("Memory mapped at address %p\n", addr);// 使用映射的内存int *array = (int *)addr;for (int i = 0; i < length / sizeof(int); i++) {array[i] = i;}// 取消映射if (munmap(addr, length) == -1) {perror("munmap failed");return 1;}return 0;
}

综合,malloc内部的分叉逻辑:

  1. 小内存块(例如几 KB):通过 brk 调整堆的大小。
  2. 大内存块(通常超过一定阈值,如 128 KB):通过 mmap 分配匿名内存区域。

用户态到内核态流程的 Mermaid 图

graph TDA[User Application] -->|malloc| B[glibc]B -->|small allocation| C[brk/sbrk]B -->|large allocation| D[mmap]C -->|System Call| E[Kernel: Adjust Heap]D -->|System Call| F[Kernel: Map Memory Pages]E --> G[Allocate Physical Memory]F --> G[Allocate Physical Memory]

内存分配的 Mermaid 图示

graph TDA[Heap Start] -->|Expand by brk/sbrk| B[Heap End]C[Anonymous Memory Region] -->|mmap| D[Virtual Address Space]E[Kernel Memory Manager] -->|Page Allocation| F[Physical Memory]

解释:

  1. Heap Start 和 Heap End 表示由 brk/sbrk 管理的堆区域。
  2. Anonymous Memory Region 是通过 mmap 分配的虚拟内存。
  3. Kernel Memory Manager 负责将虚拟地址映射到物理内存页。

最小程序加载后的内存分布示意图(演示brk/sbrk直接在Heap区域分配小内存)

graph TDH[Kernel Space] --> G[Stack]G --> F[Unmapped Memory]F --> E[Heap End]E -->|brk/sbrk| D[Heap Start]D --> C[Uninitialized Data Segment]C --> B[Initialized Data Segment]B --> A[Program Static Code Segment]

解释:

  1. Kernel Space:内核空间。
  2. Stack:存储函数调用的栈帧和局部变量。
  3. Unmapped Memory:未映射的内存区域。
  4. Heap Start 和 Heap End:由 brk/sbrk 管理的堆区域。
  5. Uninitialized Data Segment:存储未初始化的全局和静态变量(BSS段)。
  6. Initialized Data Segment:存储已初始化的全局和静态变量。
  7. Program Static Code Segment:存储程序的代码。

mmap 分配匿名内存区域的示意图

  1. Anonymous Memory Region 是通过 mmap 分配的虚拟内存。
  2. mmap 分配的内存区域不在 HEAP 区域内,因为 mmap 直接在虚拟地址空间中分配内存,而不依赖于堆的增长。堆的增长是通过 brk/sbrk 系统调用来管理的,而 mmap 则用于分配较大的内存块或特定用途的内存区域,如共享内存或文件映射。这样可以避免堆和 mmap 分配的内存区域相互干扰,提高内存管理的灵活性和效率。
graph TDH[Kernel Space] --> G[Stack End]G[Stack End] --> F[Stack Start]F[Stack Start] --> E[Unmapped Memory]E --> I[Anonymous Memory Region]I --> J[Unmapped Memory]J --> D[Heap End]D --> C[Heap Start]C --> B[Uninitialized Data Segment]B --> A[Program Static Code Segment]

解释:

  1. Stack Start 和 Stack End:表示栈的起始和结束位置。
  2. Anonymous Memory Region 是通过 mmap 分配的虚拟内存,位于栈和堆之间的未映射内存区域中。
  3. Heap Start 和 Heap End:由 brk/sbrk 管理的堆区域。
  4. Uninitialized Data Segment:存储未初始化的全局和静态变量(BSS段)。
  5. Initialized Data Segment:存储已初始化的全局和静态变量。
  6. Program Static Code Segment:存储程序的代码。

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

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

相关文章

宝藏推荐!J 人电商零售圣诞忙,哪 6 款办公软件能提升工作学习效能?

圣诞节的钟声敲响,电商零售行业瞬间陷入紧张而激烈的竞争漩涡。对于 J 人特质主导的电商团队而言,这不仅是一场销售大战,更是对团队协作与个人能力的严峻考验。在这关键时期,高效的办公软件犹如得力助手,能够帮助团队优化工作流程、提升沟通效率,实现工作与学习的双丰收。…

源码编译geoserver(idea)

官方教程:https://docs.geoserver.org/main/en/developer/quickstart/intellij.html从 git 存储库中检出源代码:git clone https://github.com/geoserver/geoserver.git geoserver列出可用的分支:% git branch2.21.x2.22.x* main选择main最新动态:% git checkout main或者为…

MFC中CBitmap、CBrush、CFont、CPalette、CPen、CRgn删除GDI对象问题

CBitmap、CBrush、CFont、CPalette、CPen、CRgn均继承自CGdiObject,CDI对象属于CGdiObject,在该类的析构函数中会释放,因此CBitmap、CBrush、CFont、CPalette、CPen、CRgn不必要显式调用DeleteObject()。如果GDI对象在在堆上分配的,则在特定时刻需要删除它,以便执行其析构…

【甲方安全】政府行业+80个威胁检测与安全事件分析场景(2025)

本篇幅详细梳理了 80 个在政企网络安全分析中常见的应用场景,这些场景涵盖了从攻击前兆(如漏洞扫描、情报收集)、攻击过程(如漏洞利用、横向移动)到攻击结果(如数据加密、信息泄露)的各个阶段,旨在协助 SOC 分析师们更好地构建主动防御体系。这些场景并非抽象概念,而是…

想自己做大模型备案的企业看过来【评估测试题+备案源文件】

大模型备案,大模型语料标注规则,大模型安全评估报告文章目录 (一)适用主体 (二)语料安全 (三)模型安全 (四)安全措施要求 (五)词库要求 (六)安全评估要求 (七)附录大模型备案材料源文件 2024年3月1日,我国通过了《生成式人工智能服务安全基本要求》(以下简称…

树洞09

情绪很不好,没人能依靠 钱财多有价,感情胜千金 金玉良缘广,木石前盟稀 愿君有真爱,伴君度此生。

qt读写ini文件

[group1]key1=val1key2=val2sameKay=sameVal [group2]jian1=zhi1jian2=zhi2sameKay=sameZhi比如创建插入一组ini文件,下面是文件写入的代码; Ini文件的写入 ini文件不需要像xml和json一样需要使用QFile打开文件,只需将文件路径及文件格式传入即可(下方代码运行完毕,ini文件…

【科普系列】LIN协议错误类型介绍

引言LIN(Local Interconnect Network)是一种针对汽车电子系统应用的串行通信协议,主要用于汽车电子控制单元(ECU)之间的通信。LIN总线的特点是成本低、速率低、通信距离短、连接节点少,主要用于对带块要求低、实时性要求不高的控制任务,例如车门控制、天窗控制、座椅控制…

详述大模型备案

大模型备案,大模型语料标注规则,大模型安全评估报告,大模型网信办备案大模型备案安全评估流程详细说明,见下图:大模型安全评估流程图 算法备案安全评估流程详细说明,见下图:算法安全评估流程图**大模型备案,大模型算法备案 ** 一、大模型算法备案的强制性 二、生成式人…

精选!J 人电商零售圣诞季,哪 6 款办公软件能激发团队工作学习潜能?

岁末的圣诞节,电商零售行业迎来了最为繁忙的购物狂欢季。在这关键时期,J 人电商团队凭借其果断、有计划、注重秩序的特质,渴望通过高效的团队协作和个人的快速学习成长,在激烈的市场竞争中脱颖而出。而选择合适的办公软件,无疑是实现这一目标的重要利器。接下来,将为您详…

智能网联汽车网络安全测试解决方案

经纬恒润的整车安全团队可协助客户制定系统的网络安全测试解决方案,具体包括:网络安全需求实现测试、网络安全合规性测试和渗透测试。经纬恒润可提供涵盖软件阶段、系统阶段和整车阶段的网络安全测试服务和相关测试工具,以实现网络安全策略的快速验证。概述为了应对日益严峻…