Применение функции HeapAlloc - нужна помощь!

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

  1. Plis

    Plis New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    26
    Доброго времени!
    Изучаю masm32 по :"Уроки Iczelion'а" . В главе 12 - http://www.wasm.ru/article.php?article=1001012 - следуя совету leo : http://www.wasm.ru/comment.php?artcode=1001012 , который в комментариях написал, что пользоваться GlobalAlloc с флагом GMEM_MOVEABLE, как не правильно, так и расточительно с точки зрения выдиления памяти, я столкнулся с проблемой использования функции HeapAlloc. В примере заменил строки :

    invoke GlobalAlloc,GMEM_MOVEABLE or

    GMEM_ZEROINIT,MEMSIZE
    mov hMemory,eax
    invoke GlobalLock,hMemory
    mov pMemory,eax

    invoke ReadFile,hFile,pMemory,MEMSIZE-1,ADDR
    SizeReadWrite,NULL
    invoke SendMessage,hwndEdit,WM_SETTEXT,NULL,pMemory
    invoke CloseHandle,hFile

    invoke GlobalUnlock,pMemory
    invoke GlobalFree,hMemory


    ---------------------- на чтение ----------------------------------------------------------------



    invoke GetProcessHeap
    mov hHeap,eax
    invoke HeapAlloc, hHeap,HEAP_ZERO_MEMORY,MEMSIZE
    mov pMemory,eax

    invoke ReadFile,hFile,pMemory,MEMSIZE-1,ADDR SizeReadWrite,NULL
    invoke SendMessage,hwndEdit,WM_SETTEXT,NULL,pMemory

    invoke HeapFree, hHeap, NULL, pMemory
    invoke CloseHandle,hFile

    ------------------ на сохранение -------------------------------------------

    invoke HeapAlloc, hHeap,HEAP_ZERO_MEMORY,MEMSIZE
    mov pMemory,eax

    invoke SendMessage, hWndEdit, WM_GETTEXT, MEMSIZE-1, pMemory
    invoke WriteFile, hFile, pMemory, eax, addr RealSize, NULL

    invoke HeapFree, hHeap, NULL, pMemory
    invoke CloseHandle, hFile

    Теперь меню Save не работает, когда печатаешь в диалоговом окне и пытаешься сохранить в файл, т.е. при попытке сохранить текст программа вылетает в отладку. Работает, когда прочитаешь из файла в диалоговое окно, а после сохраняешь в файл.
    Кто знает , просветите в применении функции HeapAlloc

    Заранее спасибо!
    зы на всякий случай прилепил файлы с неправильно действующей HeapAlloc
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ес-но, т.к. hHeap не инициализирована. Или добавь вызов GetProcessHeap перед сохранением или лучше вынеси GetProcessHeap в общую часть кода до вызова WinMain
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    PS: Неправильно юзать GlobalAlloc c флагом GMEM_MOVEABLE там где это не нужно, а с флагом GMEM_FIXED или GPTR вполне можно, т.к. при этом никакой доп.памяти не расходуется, возвращается сразу указатель на блок памяти и соотв-но никакие Lock\Unlock тоже не нужны, единственный минус - GlobalAlloc работает несколько дольше чем HeapAlloc, но в данной задаче скорости и не нужны
     
  4. Plis

    Plis New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    26
    leo - Спасибо, всё просто, исправил!
    А зачем тогда вообще использовать GlobalAlloc если она работает через HeapAlloc и, соответственно, медленнее ?
    Или существуют какие то специфические задачи, в которых GlobalAlloc нужнее HeapAlloc?
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Plis
    GlobalAlloc оствлена для совместимости с win16, в частности буфер обмена требует как раз того самого нежелательного GMEM_MOVEABLE, чтобы можно было копипастить в/из старые (например для win3.1) программы. В современных программах однозначно правильно HeapAlloc, за исключением тех случаев (Clipboard, DDE) которые требуют обязательной совместимости с программами которых уже давно нет.
     
  6. Plis

    Plis New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    26
    Y_Mur - Спасибо за инфу!
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Y_Mur
    К сожалению дело не в самой совместимости, а еще и в корявости ее реализации, особенно для работы с клипбордом. Мало того, что само использование GMEM_MOVEABLE требует доп.резерва адресов и затрат физ памяти, но еще и при работе с клипбордом "скопированный" или "вставленный" кусок памяти не удаляется виндой из нашей кучи сразу после использования, а может сидеть в ней сколько угодно долго до следующего вызова OpenClipboard или ExitProcess ;)
    А кого-то еще по наивности затраты памяти в проге волнуют, возможные утечки памяти беспокоят - мелкософтам же все эти мелочи пофиг, пока рак на горе не свистнет или гром не грянет, винда и не почешется удалять блок из нашей "приватной" "мусорной" кучи ;) Кто скажет, что такое дурное поведение обусловлено совместимостью с Win16 ? Почему для Win32 нельзя было создать доп.функции для работы с кучей (типа Set\GetClipboardDataEx), которые бы только передавали\забирали данные в\из буфера пользователя, а не требовали бы обязательного выделения блока в куче с запретом его удаления самим юзером ?
     
  8. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    leo
    Полностью согласен что клипборд реализован очень криво и нелепо - имхо гораздо лучше было в win32 сделать принипиально новый механизм работы, действующий параллельно со старым и откорректировать старые win 16 функции так чтобы они имели "окольный" доступ к данным из этого нового механизма. Пусть бы лучше старые функции стали от этого ещё кривее и тромознее - всё равно они только доживают свой век, чем портить новые программы такой "совместимостью". Но увы сделали совместимость "как сделали", остаётся только использовать как есть - сам же не перепишешь всё это безобразие из-за той же необходимости поддерживать совместимость с тем что есть теперь.