Win32编程

6、内存管理

1、课程目标

  1. 理解Windows内存管理架构
  2. 掌握虚拟内存API的使用
  3. 学会堆内存管理
  4. 掌握内存保护和操作技术

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、课后作业

  1. 基础练习:实现自定义内存池
  2. 内存保护:演示不同页面保护属性的效果
  3. 跨进程操作:读取另一个进程的内存数据
  4. 内存泄漏检测:使用HeapWalk遍历堆