当前位置: 首页 > java >正文

内存管理(Linux程序设计)

内存管理

目录

内存管理

一.简单的内存分配

代码功能概述

代码流程图

变量声明

动态内存分配

内存分配错误检查

向内存写入字符串

设置退出状态并退出程序

二.请求全部的物理内存

代码功能概述

变量声明

三..可用内存

四.滥用内存

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)  //宏定义,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_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++;                             // 累计块数 +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);
    }

http://www.xdnf.cn/news/1551.html

相关文章:

  • [SystemVerilog]例化
  • 【蓝桥杯】 数字诗意
  • 使用Python创建带边框样式的Word表格
  • 利用爬虫获取 1688 商品详情:高效的数据采集方法
  • sglang部署DeepSeek-R1-Distill-Qwen-7B
  • box-sizing: border-box的用法和作用
  • C++开发基础之调试宏的理解和应用
  • 3.2 Agent核心能力:感知、规划、决策与执行
  • MineWorld,微软研究院开源的实时交互式世界模型
  • MySQL安装步骤
  • 【AI大模型】推理大模型与预训练大模型:架构差异与认知范式的技术解构
  • SpringBoot入门实战(第六篇:项目接口-登录)
  • AXOP39062: 25MHz轨到轨输入输出双通道运算放大器
  • 计算机网络 第二章:应用层(三)
  • rpm包管理
  • NAS功能特点及应用场景
  • 工作记录9
  • AI大模型和人脑的区别
  • VAE-LSTM异常检测模型复刻报告
  • 前端笔记-Vue router
  • 自主可控鸿道Intewell工业实时操作系统
  • 量子跃迁:Vue组件安全工程的基因重组与生态免疫(完全体)
  • Spring AI - Redis缓存对话
  • 第五章:5.3 ESP32物联网应用:阿里云IoT平台与腾讯云IoT平台的数据上传与远程控制
  • 阻塞式队列
  • 非关系型数据库 八股文 Redis相关 缓存雪崩 击穿 穿透
  • Vite/Rollup 模块热更新
  • Springboot整合Redis主从
  • Java基础系列-HashMap源码解析2-AVL树
  • Java内存模型之JMM