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

内存管理(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);
    }

相关文章:

  • 宿主机和容器 ping 不通域名解决方法
  • 51c大模型~合集120
  • 汽车可变转向比系统的全面认识
  • Linux下载与安装
  • Python内置函数---breakpoint()
  • 基于deepseek的模型微调
  • 校园外卖服务系统的设计与实现(代码+数据库+LW)
  • 智能客服开发实战:用ONE-API构建多模态对话系统
  • 第1节:Backtrader到底是个啥?能干嘛?
  • c语言指针3
  • 免费且开源的企业级监控解决方案:Zabbix
  • JEnv-for-Windows​管理JDK版本
  • 如何提升个人解决问题的能力?
  • 【论文精读】Reformer:高效Transformer如何突破长序列处理瓶颈?
  • 本地服务器 Odoo 安装指南,并实现公网访问
  • STM32提高篇: 蓝牙通讯
  • 服务器上部署Nginx的几种方式
  • 位运算知识
  • 第九篇:系统分析师第三遍——5、6章
  • 相机中各个坐标系的转换关系如像素坐标系到世界坐标系以及相机标定的目的
  • 长三角与粤港澳大湾区融合发展,无锡何以成为窗口?
  • 刺激视网膜可让人“看”到全新颜色
  • 印控克什米尔发生恐袭事件,外交部:中方反对一切形式的恐怖主义
  • 乌克兰关切有中国人在俄军中服务,外交部:坚决反对无端指责
  • 为青少年写新中国成立的故事,刘统遗著《火种》出版
  • 浙江桐乡征集涉企行政执法问题线索,含乱收费、乱罚款、乱检查等