Работая с мапингом под виндой, столкнулся с такой проблемой, не получается зарезервировать буфер под MapViewOfFileEx.
При работе с файлом, как я понимаю, используется DMA, DMA позволяет ускорить обращение к памяти, если делается "выровняное" обращение. Если вызвать функцию с NULL указателем, то Windows сама определит место для мапинга, калькуляция занимает время... но... всётаки, можно ли "зараннее" зарезервировать место для мапинга? И быть уверенным, что окно всегда есть, и его никто "не украдёт" (что будет свободный линейный кусок на 64к)? Вот так реализовал я "повторный" мапинг. Если я подсовываю буфер, который зарезервировал с помощью VirtualAlloc MEM_RESERVE или MEM_RESERVE + MEM_COMMIT, то MapViewOfFileEx даёт ошибку
ERROR_INVALID_ADDRESS 487 (0x1E7) Attempt to access invalid address.
Пример (грубо)
DWORD AllocationGranularity = 65536;
void * mWnd = VirtualAlloc(0,AllocationGranularity , MEM_RESERVE, PAGE_READWRITE);
VirtualAlloc(mWnd,AllocationGranularity , MEM_COMMIT, PAGE_READWRITE);
void * wnd = MapViewOfFileEx(hMap, FILE_MAP_ALL_ACCESS, 0,0 AllocationGranularity,mWnd);
Или... можно использовать повторно то же место куда винда его определила, а если это место станет занятым, то сбрасывать указатель в ноль, и повторно вызывать MapViewOfFileEx
с нулём? (Но тут есть вероятность, что свободной памяти может не оказаться)
Возможно есть другое хорошее решение?
Все делается с точностью до наоборот. Вначале мапится регион с флагом SEC_RESERVE
, а потом этому региону делается MEM_COMMIT
DWORD AllocationGranularity = 65536;
HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE,
0, AllocationGranularity, NULL);
void * wnd = MapViewOfFileEx(hMap, FILE_MAP_ALL_ACCESS, 0, 0, AllocationGranularity, NULL);
void * mWnd = VirtualAlloc(wnd, AllocationGranularity, MEM_COMMIT, PAGE_READWRITE);
Проверка и обработка ошибок по вкусу
Ну и не забываем про страницы и гранулы
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Например проверять объект при очищении контейнера:
У меня аварийно завершается программа после того как я открываю диалог повторноПочему так происходить ? Может это быть из-за пустого Деструктор?...
Ясное дело, что по Стандарту вызовы malloc()/free()*, **new/delete и new[]/delete[] должны быть строго парными, иначе неопределенное поведение