内存管理(Linux程序设计)

news2025/4/24 8:04:58

内存管理

目录

内存管理

一.简单的内存分配

代码功能概述

代码流程图

变量声明

动态内存分配

内存分配错误检查

向内存写入字符串

设置退出状态并退出程序

二.请求全部的物理内存

代码功能概述

变量声明

三..可用内存

四.滥用内存

1.代码功能(预期 vs 实际)


一.简单的内存分配

代码功能概述
  1. 分配 1MB 内存:使用 malloc 动态申请一块 1MB 大小的内存空间。

  2. 写入字符串:通过 sprintf 向分配的内存中写入 "Hello World\n"。

  3. 输出内容:使用 printf 打印内存中的字符串。

  4. 错误处理:检查内存分配是否成功,根据结果设置程序退出状态。

代码流程图
开始
├─ 分配 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)  //宏定义,1MB

int 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_SUCCESSstdlib.h 定义的宏(通常为 0),表示程序正常结束。

  • exit 函数会清理资源(如缓冲区),并将 exit_code 返回给父进程(如 shell)

二.请求全部的物理内存

代码功能概述
  1. 目标:循环分配 1MB 大小的内存块,直到累计分配的内存达到 PHY_MEM_MEGS * 2 MB(当前配置为 256MB)。

  2. 操作:每次分配成功后,向内存块写入固定字符串 Hello World,并打印已分配的内存总量。

  3. 终止条件:当内存分配失败(如系统内存不足)或达到目标总量时终止程序。

#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++;                             // 累计块数 +1
        sprintf(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;  // 每次分配的大小:1KB
    int  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++;  // 累计分配 1MB
    printf("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);
    }

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

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

相关文章

element-ui、element-plus表单resetFields()无效的坑

一、基本前提&#xff1a; 1、form组件上必须要有ref 2、form-item上必须要有prop属性 二、新增/编辑用一个el-dialog时&#xff0c;先新增再编辑没问题&#xff0c;先编辑再新增未清空 原因 在没有点新增或着编辑时&#xff0c;我的el-dialog弹出框里的内容是空白的&…

计算机视觉算法实现——救生衣穿戴状态智能识别

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​​ ​​​​​​​​​​​​ ​​​​ 一、救生衣穿戴状态识别领域概述 水上安全一直是全球关注的重大问题&#xff0c;据世界卫生组…

Science Robotics 新型层级化架构实现250个机器人智能组队,“单点故障”系统仍可稳定运行

近期&#xff0c;比利时布鲁塞尔自由大学博士生朱炜煦与所在团队提出了一种创新的机器人群体架构——“自组织神经系统”&#xff08;SoNS&#xff0c;Self-organizing Nervous System&#xff09;。 它通过模仿自然界中的生物神经系统的组织原理&#xff0c;为机器人群体建立了…

手写深拷贝函数

在 JavaScript 中&#xff0c;深拷贝是指创建一个对象或数组的完全独立副本&#xff0c;包括其嵌套的对象或数组。这意味着修改副本不会影响原始对象。 以下是手写一个通用的深拷贝函数的实现&#xff1a; 深拷贝函数实现 function deepClone(target, map new WeakMap()) {//…

React 性能优化三剑客实战:告别无效重渲染!

在 Vue 中我们可能依赖 Vuex computed 进行状态共享和性能优化&#xff0c;而在 React 里呢&#xff1f;不需要用 Redux&#xff0c;靠 useContext、memo、useMemo 三剑客就能构建高性能组件通信方案&#xff01; &#x1f9e9; useContext 再回顾&#xff1a;状态共享不等于性…

APP动态交互原型实例|墨刀变量控制+条件判断教程

引言 不同行业的产品经理在绘制原型图时&#xff0c;拥有不同的呈现方式。对于第三方软件技术服务公司的产品经理来说&#xff0c;高保真动态交互原型不仅可以在开发前验证交互逻辑&#xff0c;还能为甲方客户带来更直观、真实的体验。 本文第三部分将分享一个实战案例&#…

色谱图QCPColorMap

一、QCPColorMap 概述 QCPColorMap 是 QCustomPlot 中用于绘制二维颜色图的类&#xff0c;可以将矩阵数据可视化为颜色图&#xff08;热力图&#xff09;&#xff0c;支持自定义色标和插值方式。 二、主要属性 属性类型描述dataQCPColorMapData存储颜色图数据的对象interpol…

最新扣子(Coze)案例教程:飞书多维表格按条件筛选记录 + 读取分页Coze工作流,无限循环使用方法,手把手教学,完全免费教程

大家好&#xff0c;我是斜杠君。 &#x1f468;‍&#x1f4bb; 星球群里有同学想学习一下飞书多维表格的使用方法&#xff0c;关于如何通过按条件筛选飞书多维表格中的记录&#xff0c;以及如何使用分页解决最多一次只能读取500条的限制问题。 斜杠君今天就带大家一起搭建一…

Spring AI Alibaba-02-多轮对话记忆、持久化消息记录

Spring AI Alibaba-02-多轮对话记忆、持久化消息记录 Lison <dreamlison163.com>, v1.0.0, 2025.04.19 文章目录 Spring AI Alibaba-02-多轮对话记忆、持久化消息记录多轮对话对话持久-Redis 本次主要聚焦于多轮对话功能的实现&#xff0c;后续会逐步增加更多实用内容&…

联邦元学习实现个性化物联网的框架

随着数据安全和隐私保护相关法律法规的出台&#xff0c;需要直接在中央服务器上收集和处理数据的集中式解决方案&#xff0c;对于个性化物联网而言&#xff0c;训练各种特定领域场景的人工智能模型已变得不切实际。基于此&#xff0c;中山大学&#xff0c;南洋理工大学&#xf…

实验1 温度转换与输入输出强化

知识点&#xff1a;input()/print()、分支语句、字符串处理&#xff08;教材2.1-2.2&#xff09; 实验任务&#xff1a; 1. 实现摄氏温度与华氏温度互转&#xff08;保留两位小数&#xff09; 2. 扩展功能&#xff1a;输入错误处理&#xff08;如非数字输入提示重新输入&#x…

【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…

[Godot] C#2D平台游戏基础移动和进阶跳跃代码

本文章给大家分享一下如何实现基本的移动和进阶的跳跃&#xff08;跳跃缓冲、可变跳跃、土狼时间&#xff09;以及相对应的重力代码&#xff0c;大家可以根据自己的需要自行修改 实现效果 场景搭建 因为Godot不像Unity&#xff0c;一个节点只能绑定一个脚本&#xff0c;所以我…

【Unity笔记】Unity + OpenXR项目无法启动SteamVR的排查与解决全指南

图片为AI生成 一、前言 随着Unity在XR领域全面转向OpenXR标准&#xff0c;越来越多的开发者选择使用OpenXR来构建跨平台的VR应用。但在项目实际部署中发现&#xff1a;打包成的EXE程序无法正常启动SteamVR&#xff0c;或者SteamVR未能识别到该应用。本文将以“Unity OpenXR …

使用 rebase 轻松管理主干分支

前言 最近遇到一个技术团队的 dev 环境分支错乱&#xff0c;因为是多人合作大家各自提交信息&#xff0c;导致出现很多交叉合并记录&#xff0c;让对应 log 看起来非常混乱&#xff0c;难以阅读。 举例说明 假设我们有一个项目&#xff0c;最初develop分支有 3 个提交记录&a…

【愚公系列】《Python网络爬虫从入门到精通》063-项目实战电商数据侦探(主窗体的数据展示)

&#x1f31f;【技术大咖愚公搬代码&#xff1a;全栈专家的成长之路&#xff0c;你关注的宝藏博主在这里&#xff01;】&#x1f31f; &#x1f4e3;开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主&#xff01; &#x1f…

HttpSessionListener 的用法笔记250417

HttpSessionListener 的用法笔记250417 以下是关于 HttpSessionListener 的用法详解&#xff0c;涵盖核心方法、实现步骤、典型应用场景及注意事项&#xff0c;帮助您全面掌握会话&#xff08;Session&#xff09;生命周期的监听与管理&#xff1a; 1. 核心功能 HttpSessionLi…

火山RTC 5 转推CDN 布局合成规则

实时音视频房间&#xff0c;转推CDN&#xff0c;文档&#xff1a; 转推直播--实时音视频-火山引擎 一、转推CDN 0、前提 * 在调用该接口前&#xff0c;你需要在[控制台](https://console.volcengine.com/rtc/workplaceRTC)开启转推直播功能。<br> * 调…

Spark两种运行模式与部署

1. Spark 的运行模式 部署Spark集群就两种方式&#xff0c;单机模式与集群模式 单机模式就是为了方便开发者调试框架的运行环境。但是生产环境中&#xff0c;一般都是集群部署。 现在Spark目前支持的部署模式&#xff1a; &#xff08;1&#xff09;Local模式&#xff1a;在本地…

qt画一朵花

希望大家的生活都更加美好&#xff0c;画一朵花送给大家 效果图 void FloatingArrowPubshButton::paintEvent(QPaintEvent *event) {QPainter painter(this);painter.setRenderHints(QPainter::Antialiasing);QPen pen;pen.setColor("green");pen.setWidth(5);QBrush…