内存管理(Linux程序设计)
内存管理
目录
内存管理
一.简单的内存分配
代码功能概述
代码流程图
变量声明
动态内存分配
内存分配错误检查
向内存写入字符串
设置退出状态并退出程序
二.请求全部的物理内存
代码功能概述
变量声明
三..可用内存
四.滥用内存
1.代码功能(预期 vs 实际)
一.简单的内存分配
代码功能概述
-
分配 1MB 内存:使用 malloc 动态申请一块 1MB 大小的内存空间。
-
写入字符串:通过 sprintf 向分配的内存中写入 "Hello World\n"。
-
输出内容:使用 printf 打印内存中的字符串。
-
错误处理:检查内存分配是否成功,根据结果设置程序退出状态。
代码流程图
开始
├─ 分配 1MB 内存
│ ├─ 成功 → 写入 "Hello World\n" → 打印内容 → 退出状态设为成功
│ └─ 失败 → 跳过操作,保持退出状态为失败
└─ 退出程序(返回 exit_code)
#include <unistd.h> // 包含 Unix 系统相关函数(此处未实际使用,可能为冗余包含)
#include <stdlib.h> // 包含内存分配(malloc)、程序退出(exit)等函数
#include <stdio.h> // 包含输入输出函数(printf、sprintf)#define A_MEGABYTE (1024 * 1024) //宏定义,1MBint main() {char *some_memory; // 用于存储动态分配的内存指针int megabyte = A_MEGABYTE; // 内存大小(1MB)int exit_code = EXIT_FAILURE; // 程序退出状态(初始为失败状态)some_memory = (char *)malloc(megabyte);if (some_memory != NULL) {sprintf(some_memory, "Hello World\n");printf("%s", some_memory);exit_code = EXIT_SUCCESS;}exit(exit_code);
}
变量声明
-
some_memory:指向 char 类型的指针,用于接收 malloc 返回的内存地址。
-
megabyte:将宏定义的值赋给变量,方便后续使用(实际可直接用 A_MEGABYTE)。
-
exit_code:使用 EXIT_FAILURE(通常为 1)初始化,表示程序默认以失败状态退出,后续根据内存分配结果修改。
动态内存分配
-
malloc 函数:分配 megabyte 字节的内存空间,返回指向该内存起始地址的指针(void),需强制类型转换为 char
-
返回值:若分配成功,返回非 NULL 指针;若失败(如内存不足),返回 NULL。
内存分配错误检查
-
必须检查 malloc 的返回值!若忽略此步骤,后续对 NULL 指针的解引用会导致程序崩溃(未定义行为)。
-
若分配失败,直接跳过 if 代码块,保持 exit_code = EXIT_FAILURE,程序以失败状态退出。
向内存写入字符串
sprintf(some_memory, "Hello World\n");
-
sprintf函数:将格式化字符串写入指定内存缓冲区(而非标准输出)。 -
此处作用:将 "Hello World\n" 写入
some_memory指向的内存起始位置。 -
注意:虽然分配了 1MB 内存,但字符串仅占用 12 字节("Hello World\n" 共 11 个字符 + 1 个
\0终止符),剩余内存未使用(但仍被分配)。 -
sprintf 会自动添加 \0
设置退出状态并退出程序
exit_code = EXIT_SUCCESS; // 若内存分配和写入成功,设置退出状态为成功(0)
exit(exit_code); // 终止程序,返回状态码给操作系统
-
EXIT_SUCCESS是stdlib.h定义的宏(通常为 0),表示程序正常结束。 -
exit函数会清理资源(如缓冲区),并将exit_code返回给父进程(如 shell)
二.请求全部的物理内存
代码功能概述
-
目标:循环分配 1MB 大小的内存块,直到累计分配的内存达到 PHY_MEM_MEGS * 2 MB(当前配置为 256MB)。
-
操作:每次分配成功后,向内存块写入固定字符串 Hello World,并打印已分配的内存总量。
-
终止条件:当内存分配失败(如系统内存不足)或达到目标总量时终止程序。
#include <unistd.h> // 包含 Unix 系统相关函数(此处未实际使用,可能为冗余)
#include <stdlib.h> // 包含内存分配(malloc)、程序退出(exit)等函数
#include <stdio.h> // 包含输入输出函数(printf、sprintf)#define A_MEGABYTE (1024 * 1024) // 定义 1MB 大小(1024×1024 字节)
#define PHY_MEM_MEGS 128 // 预设的物理内存大小(单位:MB),实际分配其 2 倍(256MB)int main()
{char *some_memory; // 存储每次分配的内存块指针size_t size_to_allocate = A_MEGABYTE; // 每次分配的大小(1MB)int megs_obtained = 0; // 已分配的内存总量(单位:MB)while (megs_obtained < (PHY_MEM_MEGS * 2)) {//malloc 函数:分配 size_to_allocate 字节的内存空间,返回指向该内存起始地址的指针some_memory = (char *)malloc(size_to_allocate); // 分配 1MB 内存if (some_memory != NULL) { // 分配成功megs_obtained++; // 累计块数 +1sprintf(some_memory, "Hello World"); // 向内存块写入固定字符串printf("%s - now allocated %d Megabytes\n", some_memory, megs_obtained);} else { // 分配失败(如内存不足)exit(EXIT_FAILURE); // 终止程序,返回错误状态}
}exit(EXIT_SUCCESS);
}
变量声明
char *some_memory; // 存储每次分配的内存块指针
size_t size_to_allocate = A_MEGABYTE; // 每次分配的大小(1MB)
int megs_obtained = 0; // 已分配的内存总量(单位:MB)
-
size_to_allocate 使用 size_t 类型(无符号整数),符合 malloc 参数要求,避免溢出风险。
-
megs_obtained 记录累计分配的 1MB 块数,达到 PHY_MEM_MEGS * 2 时停止。
内存分配循环
关键逻辑:
-
循环条件:(因 ,2 倍即 256MB)。megs_obtained < 256PHY_MEM_MEGS=128
-
单次分配:
malloc(size_to_allocate) 申请 1MB 内存,返回指向该内存的指针。
若返回 ,说明内存分配失败(如系统剩余内存不足),程序直接退出。NULL
-
成功处理:
megs_obtained++:累计已分配的 1MB 块数。
sprintf:向分配的内存块写入字符串 (仅占用 12 字节,剩余 1MB-12 字节未使用)。
printf:打印内存块中的字符串和当前已分配的总内存(以 MB 为单位)。
三..可用内存
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>#define ONE_K (1024)int main() {char *some_memory; // 存储单次分配的内存块指针int size_to_allocate = ONE_K; // 每次分配的大小:1KBint megs_obtained = 0; // 已分配的内存总量(单位:MB)int ks_obtained = 0; // 内层循环中已分配的 1KB 块数while (1) { // 无限循环,直到手动终止或内存不足for (ks_obtained = 0; ks_obtained < 1024; ks_obtained++) {// 分配 1KB 内存some_memory = (char *)malloc(size_to_allocate);if (some_memory == NULL) exit(EXIT_FAILURE); // 分配失败则退出sprintf(some_memory, "Hello World"); // 向内存块写入固定字符串(12 字节)}megs_obtained++; // 累计分配 1MBprintf("Now allocated %d Megabytes\n", megs_obtained); // 打印已分配的 MB 数
}exit(EXIT_SUCCESS);
}
四.滥用内存
1.代码功能(预期 vs 实际)
预期功能(推测):
分配 1KB 内存,逐个字节写入 (空字符),理论上初始化内存区域为全零。'\0'
-
实际行为:
无限循环:没有终止条件,指针会超出分配的内存范围,导致 未定义行为(如缓冲区溢出、段错误)。
-
#include <unistd.h> #include <stdlib.h>#define ONE_K (1024)int main() {//内存分配char *some_memory;char *scan_ptr;some_memory = (char *)malloc(ONE_K);if (some_memory == NULL) exit(EXIT_FAILURE);scan_ptr = some_memory;while(1) {*scan_ptr = '\0';scan_ptr++;}exit(EXIT_SUCCESS); }
相关文章:
内存管理(Linux程序设计)
内存管理 目录 内存管理 一.简单的内存分配 代码功能概述 代码流程图 变量声明 动态内存分配 内存分配错误检查 向内存写入字符串 设置退出状态并退出程序 二.请求全部的物理内存 代码功能概述 变量声明 三..可用内存 四.滥用内存 1.代码功能(预期 …...
element-ui、element-plus表单resetFields()无效的坑
一、基本前提: 1、form组件上必须要有ref 2、form-item上必须要有prop属性 二、新增/编辑用一个el-dialog时,先新增再编辑没问题,先编辑再新增未清空 原因 在没有点新增或着编辑时,我的el-dialog弹出框里的内容是空白的&…...
LeetCode 252 会议室 III(Meeting Rooms III)题解与模拟面试
1. 引言 在现代办公和协作中,会议室的高效利用至关重要。LeetCode 252 题“会议室 III”要求我们在给定一组会议的时间区间后,计算同一时间段内需要开的最少会议室数量,以保证所有会议能顺利进行。本题不仅是经典的区间调度问题变形…...
基于HPC的气候模拟GPU加速实践全流程解析
基于HPC的气候模拟GPU加速实践全流程解析 关键词:气候模型、GPU加速、CUDA编程、性能优化、分布式训练 摘要: 本文针对全球气候模拟中10^12级网格点实时计算需求,提出基于CUDA的并行计算架构。通过改进WRF模式的分块矩阵乘法算法,…...
【CSS】层叠,优先级与继承(三):超详细继承知识点
目录 继承一、什么是继承?2.1 祖先元素2.2 默认继承/默认不继承 二、可继承属性2.1 字体相关属性2.2 文本相关属性2.3 列表相关属性 三、不可继承属性3.1 盒模型相关属性3.2 背景相关属性 四、属性初始值4.1 根元素4.2 属性的初始值4.3 得出结论 五、强制继承5.1 in…...
计算机视觉算法实现——救生衣穿戴状态智能识别
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ 一、救生衣穿戴状态识别领域概述 水上安全一直是全球关注的重大问题,据世界卫生组…...
URI、URL与URN详解概念介绍
URI (Uniform Resource Identifier) URI是统一资源标识符,是用于标识互联网上资源的字符串。它是一个用于区分资源的通用标识符,可以标识任何资源,包括文档、图像、服务等。 URI的特点 提供了一种标准方法来标识资源是最广泛的资源标识概念,URL和URN都是URI的子集格式通常…...
Science Robotics 新型层级化架构实现250个机器人智能组队,“单点故障”系统仍可稳定运行
近期,比利时布鲁塞尔自由大学博士生朱炜煦与所在团队提出了一种创新的机器人群体架构——“自组织神经系统”(SoNS,Self-organizing Nervous System)。 它通过模仿自然界中的生物神经系统的组织原理,为机器人群体建立了…...
手写深拷贝函数
在 JavaScript 中,深拷贝是指创建一个对象或数组的完全独立副本,包括其嵌套的对象或数组。这意味着修改副本不会影响原始对象。 以下是手写一个通用的深拷贝函数的实现: 深拷贝函数实现 function deepClone(target, map new WeakMap()) {//…...
React 性能优化三剑客实战:告别无效重渲染!
在 Vue 中我们可能依赖 Vuex computed 进行状态共享和性能优化,而在 React 里呢?不需要用 Redux,靠 useContext、memo、useMemo 三剑客就能构建高性能组件通信方案! 🧩 useContext 再回顾:状态共享不等于性…...
深度学习3.3 线性回归的简洁实现
步骤操作作用前向计算net(X)计算预测值 y_hat Xw b损失计算loss(y_hat, y)量化预测误差,驱动参数更新反向传播l.backward()计算参数梯度参数更新trainer.step()根据梯度调整参数,逼近最优解梯度清零trainer.zero_grad()防止梯度累积(必须放…...
复盘20250422
深度分析及个股推荐 1. 行业前景与个股逻辑梳理 从提供的股票信息来看,主要涉及以下行业:合成尼古丁(电子烟)、化工、跨境支付、跨境电商、农药、食品饮料、光刻机、电子商务、造纸等。需结合行业景气度、政策支持、公司核心竞争…...
从零开始学习MySQL的系统学习大纲
文章目录 前言第一阶段:数据库与 MySQL 基础认知数据库基础概念MySQL 简介 第二阶段:MySQL 安装与环境搭建安装前的准备MySQL 安装过程安装后的配置 第三阶段:SQL 基础语法SQL 概述数据库操作数据表操作数据操作 第四阶段:SQL 高级…...
APP动态交互原型实例|墨刀变量控制+条件判断教程
引言 不同行业的产品经理在绘制原型图时,拥有不同的呈现方式。对于第三方软件技术服务公司的产品经理来说,高保真动态交互原型不仅可以在开发前验证交互逻辑,还能为甲方客户带来更直观、真实的体验。 本文第三部分将分享一个实战案例&#…...
基于控制台的小车导航游戏开发详解(C++实现)
本文将详细讲解一个基于C控制台的小车导航游戏项目。通过该项目可以学习二维数组操作、队列数据结构应用以及游戏循环控制等核心编程概念,特别适合刚接触游戏开发的初学者学习。 一、项目概述 1.1 游戏规则 玩家可创建多辆具有不同初始位置和移动速度的小车 每辆…...
色谱图QCPColorMap
一、QCPColorMap 概述 QCPColorMap 是 QCustomPlot 中用于绘制二维颜色图的类,可以将矩阵数据可视化为颜色图(热力图),支持自定义色标和插值方式。 二、主要属性 属性类型描述dataQCPColorMapData存储颜色图数据的对象interpol…...
大文件分片上传进阶版(新增md5校验、上传进度展示、并行控制,智能分片、加密上传、断点续传、自动重试),实现四位一体的网络感知型大文件传输系统
上篇文章我们总结了大文件分片上传的主要核心,但是我对md5校验和上传进度展示这块也比较感兴趣,所以在deepseek的帮助下,扩展了一下我们的代码,如果有任何问题和想法,非常欢迎大家在评论区与我交流,我需要学…...
oracle不同数据库版本的自增序列
-- 查看数据库版本 SELECT * FROM v$version WHERE banner LIKE Oracle%; 1. Oracle 12c及以上版本支持 id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, id NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1) PRIMARY KEY, -- 语法 id NUMBER GENER…...
【KWDB创作者计划】_针对KWDB时序数据库(多副本集群环境)进行压力测试
【KWDB创作者计划】_针对KWDB时序数据库(多副本集群环境)进行压力测试 1. 概述2. 压测环境部署3. 生成测试数据4. 写入性能测试5. 查询性能测试7. 总结 1. 概述 KaiwuDB分布式多模数据库从物联网场景真实需求出发,针对性设计多模架构。物联网…...
极狐GitLab 自定义实例级项目模板功能介绍
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 自定义实例级项目模板 (PREMIUM SELF) 极狐GitLab 管理员可以将群组设置为在实例上创建新项目时可选择的项目模板的来源。然…...
最新扣子(Coze)案例教程:飞书多维表格按条件筛选记录 + 读取分页Coze工作流,无限循环使用方法,手把手教学,完全免费教程
大家好,我是斜杠君。 👨💻 星球群里有同学想学习一下飞书多维表格的使用方法,关于如何通过按条件筛选飞书多维表格中的记录,以及如何使用分页解决最多一次只能读取500条的限制问题。 斜杠君今天就带大家一起搭建一…...
第八天 AI开发:NavMesh导航系统 对话系统:使用ScriptableObject存储对话数据 存档系统:JSON序列化保存数据
一、智能导航系统:NavMesh实战指南 1.1 导航网格基础配置 在Unity编辑器中: 选择场景中的静态物体勾选Navigation Static属性打开Window > AI > Navigation窗口 烘焙参数设置: NavMeshBuildSettings settings NavMesh.GetSettingsBy…...
Spring AI Alibaba-02-多轮对话记忆、持久化消息记录
Spring AI Alibaba-02-多轮对话记忆、持久化消息记录 Lison <dreamlison163.com>, v1.0.0, 2025.04.19 文章目录 Spring AI Alibaba-02-多轮对话记忆、持久化消息记录多轮对话对话持久-Redis 本次主要聚焦于多轮对话功能的实现,后续会逐步增加更多实用内容&…...
联邦元学习实现个性化物联网的框架
随着数据安全和隐私保护相关法律法规的出台,需要直接在中央服务器上收集和处理数据的集中式解决方案,对于个性化物联网而言,训练各种特定领域场景的人工智能模型已变得不切实际。基于此,中山大学,南洋理工大学…...
做虚拟化应该怎么选择美国服务器?
选择适合做虚拟化的美国服务器,需要综合考虑硬件性能、网络质量、稳定性、价格和服务支持等多个方面。以下是详细的选购指南,适合准备搭建VPS、虚拟主机、分销业务、开发测试环境、容器集群等用途的用户参考。 一、为什么美国服务器适合虚拟化? 美国机房…...
实验1 温度转换与输入输出强化
知识点:input()/print()、分支语句、字符串处理(教材2.1-2.2) 实验任务: 1. 实现摄氏温度与华氏温度互转(保留两位小数) 2. 扩展功能:输入错误处理(如非数字输入提示重新输入&#x…...
MongoDB 集合名称映射问题
项目场景 在使用 Spring Data MongoDB 进行开发时,定义了一个名为 CompetitionSignUpLog 的实体类,并创建了对应的 Repository 接口。需要明确该实体类在 MongoDB 中实际对应的集合名称是 CompetitionSignUpLog 还是 competitionSignUpLog。 问题描述 …...
【AI】SpringAI 第五弹:接入千帆大模型
1. 添加依赖 <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-qianfan</artifactId> </dependency> 2. 编写 yml 配置文件 spring:ai:qianfan:api-key: 你的api-keysecret-key: 你的secr…...
【编码规范】原生开发 与 Vue+组件库开发
原生开发 vs Vue组件库开发对比 一、原生开发常用方法 DOM操作: document.getElementById()document.querySelector()element.addEventListener()classList API操作类名 事件处理: 直接事件绑定事件委托 document.body.addEventListener(click, functi…...
[Godot] C#2D平台游戏基础移动和进阶跳跃代码
本文章给大家分享一下如何实现基本的移动和进阶的跳跃(跳跃缓冲、可变跳跃、土狼时间)以及相对应的重力代码,大家可以根据自己的需要自行修改 实现效果 场景搭建 因为Godot不像Unity,一个节点只能绑定一个脚本,所以我…...
