内存管理
目录
内存管理
一.简单的内存分配
代码功能概述
代码流程图
变量声明
动态内存分配
内存分配错误检查
向内存写入字符串
设置退出状态并退出程序
二.请求全部的物理内存
代码功能概述
变量声明
三..可用内存
四.滥用内存
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) //宏定义,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_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++; // 累计块数 +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); }