1、申请内存的两种方式
<1>通过VirtualAlloc/VirtualAllocEx申请的:PrivateMemory(当前的线性地址独享物理页)
<2>通过CreateFileMapping映射的:Mapped Memory(线性地址对应的物理页可能不是独有的,可能与其他进程共享物理页)
2、申请内存
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的内存区域的地址
DWORD dwSize, // 分配的大小,按页的大小分,小于一个页也按一个页分
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
};
实验代码:
#include
#include
LPVOID lpAddress;
int main()
{
printf("程序运行了,内存还没有申请\n");
getchar();
//要申请的内存,申请内存的线性地址;大小,以页为单位;保留还是提交,MEM_RESERVER|MEM_COMMIT;访问权限
lpAddress = ::VirtualAlloc(NULL, 0x1000 * 2, MEM_COMMIT, PAGE_READWRITE);
printf("申请的线性地址为:%x\n", lpAddress);
getchar();
return 0;
}
步骤:
首先,我们先运行程序停下来,然后在WinDbg中查看该程序的内存分配情况
kd> !vad 0x8667a2c0
VAD Level Start End Commit
86699ed8 1 10 10 1 Private READWRITE
868ccd18 2 20 20 1 Private READWRITE
866f5288 3 30 12f 3 Private READWRITE
8672a210 4 130 132 0 Mapped READONLY Pagefile section, shared commit 0x3
8673dc48 5 140 23f 4 Private READWRITE
86a4e6e8 6 240 24f 6 Private READWRITE
86ab0488 7 250 25f 0 Mapped READWRITE Pagefile section, shared commit 0x3
86955c60 8 260 275 0 Mapped READONLY \WINDOWS\system32\unicode.nls
865fbd48 9 280 2c0 0 Mapped READONLY \WINDOWS\system32\locale.nls
8689b670 10 2d0 310 0 Mapped READONLY \WINDOWS\system32\sortkey.nls
868d7840 11 320 325 0 Mapped READONLY \WINDOWS\system32\sorttbls.nls
868c8b30 12 330 370 0 Mapped READONLY Pagefile section, shared commit 0x41
865fbc98 13 380 38f 8 Private READWRITE
86ad42f0 14 390 392 0 Mapped READONLY \WINDOWS\system32\ctype.nls
8667a2c0 0 400 426 4 Mapped Exe EXECUTE_WRITECOPY \MSDev98\MyProjects\VirtualAlloc\Debug\VirtualAlloc.exe
86ab02c8 3 430 52f 8 Private READWRITE
868de588 2 7c800 7c91d 6 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\kernel32.dll
867b26a8 1 7c920 7c9b5 5 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\ntdll.dll
86a3fd90 3 7f6f0 7f7ef 0 Mapped EXECUTE_READ Pagefile section, shared commit 0x7
862184e8 2 7ffa0 7ffd2 0 Mapped READONLY Pagefile section, shared commit 0x33
86a48008 3 7ffda 7ffda 1 Private READWRITE
8667a3a8 4 7ffdf 7ffdf 1 Private READWRITE
Total VADs: 22, average level: 6, maximum depth: 14
Total private commit: 0x30 pages (192 KB)
Total shared commit: 0x81 pages (516 KB)
接着我们回到虚拟机继续执行程序,然后回到WinDbg中查看内存分配情况
3、堆与栈
C中的堆是操作系统先用VirtualAlloc分配了很大一块内存,当我们使用malloc是调用HeapAlloc,HeapAlloc分配内存是从操作系统中分好的内存直接拿来用,malloc函数使用的时候根本没有进0环
栈也是操作系统已经分配好的内存
实验代码
#include
#include
int x = 0x1111;
int main()
{
printf("申请内存前\n");
getchar();
int y = 0x2222;
int *z = (int*)malloc(sizeof(int) * 128);
printf("全局变量:%x\n", &x);
printf("栈:%x\n", &y);
printf("堆:%x\n", z);
getchar();
return 0;
}
首先,我们先运行代码并用WinDbg查看内存分配状况
然后继续运行代码,再回到WinDbg中查看内存
对比两图,发现全局变量是Mapped内存,其他两个也是提前分配好的