В чем разница между BaseAddress и AllocationBase в структуре базовой информации памяти?

в MSDN я нахожу следующее'

BaseAddress-указатель на базовый адрес области страниц.

AllocationBase-указатель на базовый адрес диапазона страниц, выделенных функцией VirtualAlloc. Страница, на которую указывает элемент BaseAddress, содержится в этом диапазоне распределения.

но я не понимаю, какая разница на самом деле. Кто-нибудь может сказать мне разницу? (не как в MSDN :) )

1 ответов


выделения виртуальной памяти в Windows производятся с детализацией 64 килобайта, значением SYSTEM_INFO.dwAllocationGranularity. Но страницы виртуальной памяти составляют 4096 байт, значение SYSTEM_INFO.dwPageSize.

когда вы выделяете виртуальную память с VirtualAlloc, вы всегда получите кусок назад, чей BaseAddress равен AllocationBase. Но если вы затем измените защиту страницы одной или нескольких страниц в этом фрагменте, вы можете наблюдать, что этот фрагмент подразделяется с другим BaseAddress. Лучше всего показано с образцом программы, запустите это на MSVC++:

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <conio.h>

void showmem(void* mem) {
    MEMORY_BASIC_INFORMATION info = {};
    VirtualQuery(mem, &info, sizeof info);
    printf("Alloc = %p, base = %p, size = %d, protect = %d\n",
           info.AllocationBase, info.BaseAddress, info.RegionSize, info.Protect);
}


int main() {
    BYTE* mem = (BYTE*)VirtualAlloc(0, 65536, MEM_COMMIT, PAGE_READWRITE);
    printf("%s", "Initial allocation:\n");
    showmem(mem);

    DWORD oldprotect;
    BOOL ok = VirtualProtect(mem + 4096, 4096, PAGE_NOACCESS, &oldprotect);
    printf("%s", "\nAfter protection changes:\n");
    showmem(mem);
    showmem(mem + 4096);
    showmem(mem + 4096 + 4096);

    _getch();
    return 0;
}

пример вывода этой программы:

Initial allocation:
Alloc = 00ED0000, base = 00ED0000, size = 65536, protect = 4

After protection changes:
Alloc = 00ED0000, base = 00ED0000, size = 4096, protect = 4
Alloc = 00ED0000, base = 00ED1000, size = 4096, protect = 1
Alloc = 00ED0000, base = 00ED2000, size = 57344, protect = 4

и обратите внимание, как вызов VirtualProtect () требовал, чтобы исходный фрагмент был разделен на 3 области с разным BaseAddress, но той же AllocationBase.