Win32编程
6、内存管理
1、课程目标
- 理解Windows内存管理架构
- 掌握虚拟内存API的使用
- 学会堆内存管理
- 掌握内存保护和操作技术
2、名词解释
| 术语 | 英文 | 说明 |
|---|---|---|
| 虚拟内存 | Virtual Memory | 每个进程的独立地址空间 |
| 页 | Page | 内存管理的最小单位(4KB) |
| 提交 | Commit | 为虚拟地址分配物理内存 |
| 保留 | Reserve | 仅保留虚拟地址范围 |
3、代码实现
3.1、示例1:VirtualAlloc
#include <windows.h>
#include <stdio.h>
void VirtualMemoryDemo() {
// 保留并提交内存
LPVOID pMem = VirtualAlloc(
NULL, // 系统选择地址
4096, // 大小
MEM_RESERVE | MEM_COMMIT, // 保留并提交
PAGE_READWRITE // 读写权限
);
if (pMem) {
// 使用内存
strcpy((char*)pMem, "Hello Virtual Memory!");
printf("%s\n", (char*)pMem);
// 修改保护属性为只读
DWORD oldProtect;
VirtualProtect(pMem, 4096, PAGE_READONLY, &oldProtect);
// 释放内存
VirtualFree(pMem, 0, MEM_RELEASE);
}
}
3.2、示例2:堆内存管理
#include <windows.h>
#include <stdio.h>
void HeapDemo() {
// 创建私有堆
HANDLE hHeap = HeapCreate(0, 0, 0);
if (hHeap) {
// 从私有堆分配
void* p1 = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 1024);
void* p2 = HeapAlloc(hHeap, 0, 2048);
// 重新分配
p1 = HeapReAlloc(hHeap, 0, p1, 4096);
// 释放
HeapFree(hHeap, 0, p1);
HeapFree(hHeap, 0, p2);
// 销毁堆
HeapDestroy(hHeap);
}
// 使用进程默认堆
HANDLE hDefault = GetProcessHeap();
void* pDefault = HeapAlloc(hDefault, 0, 1024);
HeapFree(hDefault, 0, pDefault);
}
3.3、示例3:内存信息查询
#include <windows.h>
#include <stdio.h>
void QueryMemoryInfo(LPVOID addr) {
MEMORY_BASIC_INFORMATION mbi;
if (VirtualQuery(addr, &mbi, sizeof(mbi))) {
printf("Base: %p\n", mbi.BaseAddress);
printf("Alloc Base: %p\n", mbi.AllocationBase);
printf("Size: %lld\n", mbi.RegionSize);
printf("State: %s\n",
mbi.State == MEM_COMMIT ? "Commit" :
mbi.State == MEM_RESERVE ? "Reserve" : "Free");
printf("Protect: 0x%X\n", mbi.Protect);
}
}
3.4、示例4:跨进程内存操作
#include <windows.h>
#include <stdio.h>
void ReadProcessMemoryDemo(DWORD pid, LPVOID addr) {
HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, pid);
if (hProcess) {
char buffer[256];
SIZE_T bytesRead;
if (ReadProcessMemory(hProcess, addr, buffer, sizeof(buffer), &bytesRead)) {
printf("Read %lld bytes\n", bytesRead);
}
CloseHandle(hProcess);
}
}
void WriteProcessMemoryDemo(DWORD pid, LPVOID addr, void* data, SIZE_T size) {
HANDLE hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
if (hProcess) {
SIZE_T bytesWritten;
WriteProcessMemory(hProcess, addr, data, size, &bytesWritten);
CloseHandle(hProcess);
}
}
4、课后作业
- 基础练习:实现自定义内存池
- 内存保护:演示不同页面保护属性的效果
- 跨进程操作:读取另一个进程的内存数据
- 内存泄漏检测:使用HeapWalk遍历堆