VirtualAlloc, выделять память подряд

Тема в разделе "WASM.WIN32", создана пользователем rudik, 3 янв 2009.

  1. rudik

    rudik Руденко Артём

    Публикаций:
    0
    Регистрация:
    6 дек 2006
    Сообщения:
    302
    Адрес:
    г. Харьков
    Короче проблема в следующем. Выделяю блок памяти размером в 4кб, получаю указатель,
    выделяю ещё раз 4 кб - получаю ещё один указатель. Сравниваю их - разница в 0x10000,
    а должно быть в 0x1000. Между блоками никаких зарегестрированых участков нет.
    Флаг MEM_TOP_DOWN дает тот же результат, только с конца пространства пользователя.
    Подскажите метод или способ как можно выделять участки подряд, желательно без ручного
    управления и увеличения размера выделения до 0х10000.
     
  2. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    VirtualAlloc выделяет память блоками, выравненными на 64Kb
     
  3. rudik

    rudik Руденко Артём

    Публикаций:
    0
    Регистрация:
    6 дек 2006
    Сообщения:
    302
    Адрес:
    г. Харьков
    Все, разобрался, спасибо.
     
  4. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    rudik
    если хочешь предсказуемой работы VirtualAlloc обязательно сначала резервируй диапазон адресов, потом в нём уже выделяй страницы по мере необходимости
    http://www.wasm.ru/forum/viewtopic.php?pid=167377#p167377
    http://www.wasm.ru/forum/viewtopic.php?pid=270546#p270546
     
  5. lobzik

    lobzik New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2009
    Сообщения:
    34
    Народ, проблема такая, распаковал я одну программу, но распаковал криво (пользовался распаковщиком), при запуске, распаковщик пытается прочитать страницу памяти по одному и тому же адресу, а ее нет и вылетает, но если я задаю в Ольке валидный участок то прога запускается как нада. А проблема в том, что я никак не могу выделить участок памяти по нужному адресу (00141000), vmmap показывает 60кб, т.е до адреса 00150000 (стека), а тут почитал что VirtualAlloc может тока 64 кб резервировать ?? Как быть ?
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Резервировать можно минимум одну страницу, это 4k.
    Что возвращается за код ошибки при выделении памяти и состояние региона какое ?
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    lobzik
    Если 64К регион 140000h свободен, то и запрашивай выделение по адресу 140000h с флагами MEM_RESERVE+MEM_COMMIT. А если этот регион уже зарезервирован и в нем выделена одна страница, то запрашивай память по адресу 141000h с флагом MEM_COMMIT
     
  8. lobzik

    lobzik New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2009
    Сообщения:
    34
    Clerk состояние FREE, код ошибки 487 (dec).
    leo, регион свободен, но не получается выделить, ошибка, нужно именно там где нужно.
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Значит STATUS_CONFLICTING_ADDRESSES.
    Значит вызывай NtQueryVirtualMemory(MemoryBasicInformation) для этого региона, там видно будет.
     
  10. lobzik

    lobzik New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2009
    Сообщения:
    34
    Видимо эти участки памяти как то зарезервированы системой, но всеравно же их можно как то увеличить .. от чего они зависят ? мб можно как то при запуске программы увеличить?
     
  11. lobzik

    lobzik New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2009
    Сообщения:
    34
    NtQueryVirtualMemory(MemoryBasicInformation) = VirtualQuery если я неошибаюсь, она показывает State Free и Protect ReadOnly.
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    MEM_RESERVE убери.
     
  13. lobzik

    lobzik New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2009
    Сообщения:
    34
    Вощем спасибо всем ) проблема решилась другим способом, подредактировав ПЕ хедер, увеличил стэк до размера нужной секции, вощем рабтает и ладно ))
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    lobzik
    Я вроде ясно выразился - зарезервировать память можно только по адресу, кратному 64К. Поэтому если ты юзаешь MEM_RESERVE+MEM_COMMIT, то запрашивай адрес 140000h и соотв-но увеличь запрашиваемый размер на 4К (че те жалко лишнюю страницу прихватить ?). Если страница по адресу 140000h занята (о чем видимо свидетельствует MEM_FREE + PAGE_READONLY), то нужно запрашивать память по адресу 141000h только с флагом MEM_COMMIT, т.к. этот регион уже "кем-то" зарезервирован до тебя
     
  15. lobzik

    lobzik New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2009
    Сообщения:
    34
    Насчет резервирования понятно, но всеравно она(функция) нехочет делать так как нада, она резервирует тока гдето в другом месте, т.е запрашиваю память по адресу 141000h только с флагом MEM_COMMIT(при условии что это свободная память и никем незарезервирована), а мне гдето из бутово поинтер прилетает. Вот сам попробуй расшарить страницу гденибуть в 00130000 или 00140000, хотябы 4кб.
     
  16. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    lobzik
    Не-е, ты не lobzik, ты buzz-saw - как пошел пилить в одном направлении, так и шуруешь, не слыша что тебе говорят :)

    Последний раз повторяю, раз память по адресу 141000h НЕ зарезервирована (MEM_FREE), то VirtualAlloc в принципе не может вернуть тебе этот адрес, т.к. начальный адрес для резервирования всегда округляется вниз на границу 64К. Поэтому и нужно запрашивать память по кратному адресу 140000h, но размер задать так, чтобы он захватил и нужный тебе адрес 141000h. Если все будет OK и VirtualAlloc вернет адрес 140000h, то просто прибавишь к нему 1000h и получишь свой адрес 141000h. Как ты не поймешь, что дело не в начальном адресе выделенного блока, а в том, чтобы этот выделенный блок накрыл твой адрес 141000h - тогда все будет ОК
     
  17. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    PS: Да, и с размером не промахнись, а то можешь выскочить на следующий зарезервированный блок и опять получишь облом-с
     
  18. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    leo
    Какие 64k ?
    У меня одна страница чудесно так резервируется.
     
  19. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Clerk
    А я разве говорил, что нельзя резервировать меньше 64К ?
    Просто начальный адрес для резерва всегда округляется вниз на 64К границу, поэтому если задавать размер резерва меньше (или некратным) 64К, то оставшиеся свободные страницы в конце 64К-блока будут вообще не доступны, т.к. увеличить размер резерва повторным вызовом VirtualAlloc в этом случае не получиться.
     
  20. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    PS: Поэтому я и толкую, что раз страница 141000h не зарезервирована (MEM_FREE), то нужно проверить состояние предыдущей выравненной страницы 140000h - если она тоже MEM_FREE, до удасться зарезервировать и выделить нужное число страниц по этому адресу, прихватив и 141000h, и еще сколько нужно. А если память по адресу 140000h уже зарезервирована\выделена, то ловить тут вообще нечего
    PPS: речь ес-но идет о VirtualAlloc, че там у вас в нативе или в ядре творится, я не знаю ;)