1、申請內存的兩種方式
<1>通過VirtualAlloc/VirtualAllocEx申請的:PrivateMemory(當前的線性地址獨享物理頁)
<2>通過CreateFileMapping映射的:Mapped Memory(線性地址對應的物理頁可能不是獨有的,可能與其他進程共享物理頁)
2、申請內存
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的內存區域的地址
DWORD dwSize, // 分配的大小,按頁的大小分,小於一個頁也按一個頁分
DWORD flAllocationType, // 分配的類型
DWORD flProtect // 該內存的初始保護屬性
};
實驗代碼:
#include <windows.h>
#include <stdio.h>
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 <stdio.h>
#include <stdlib.h>
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內存,其他兩個也是提前分配好的