Выделение памяти...

Тема в разделе "WASM.BEGINNERS", создана пользователем dgs, 21 ноя 2008.

  1. dgs

    dgs New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2008
    Сообщения:
    434
    Привет всем, я хотел спросить бы две вещи какой способ выделение памяти в винде лучше, GlobalAlloc, VirtualAlloc и т.п. ? И почему у меня не выделяется HGLOBAL в проге, просто давно не содился за ассемблер и может я, что делаю не так? syntax = fasm:
    Заранее благодарю...
     
  2. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Все элементарно ватсон. У тебя указано GMEM_ZEROINIT, а это получается
    GMEM_ZEROINIT+GMEM_FIXED
    (GMEM_FIXED=0)
    а оно возвращает сразу же указатель (сразу же после GlobalAlloc).
    Для создания кучи оставь Global. Тебе же не надо управляться с виртуальным пространством. тем более что тебе тут вообще без разници где память лежит.
     
  3. dgs

    dgs New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2008
    Сообщения:
    434
    Спс, а я то головой об стену бьюсь...

    А в чем проблема GlobalReAlloc???
     
  4. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Никогда не понимал зачем нужно усложнять.
    Вся память общая, любой поток к ней доступ имеет.
    Эффективнее и проще вызвать сервис NtAllocateVirtualMemory, либо если нужно из хипа память, то функций управления им множество.
     
  5. dgs

    dgs New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2008
    Сообщения:
    434
    Nt - я конечно в этом плохо разбираюсь, но функции с таким прификсом вроде вызываються с приложений работающих в ring0 или я не прав?, а мне надо сделать тупую прогу которая могла бы записовать и читать в файл древовидную структуру данных...
     
  6. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Вот простой макрос (FASM). По аналогии можно сделать и для free(), realloc():
    Код (Text):
    1. macro malloc nBytes
    2. {
    3.     invoke  GetProcessHeap
    4.     invoke  HeapAlloc, eax, HEAP_NO_SERIALIZE, nBytes
    5. }
     
  7. lamer2k

    lamer2k New Member

    Публикаций:
    0
    Регистрация:
    14 май 2006
    Сообщения:
    88
    По поводу способа выделения памяти мс написали вот как:
    Другими словами, работа с памятью, используя эти функции, уже стала историей :) как и Windows 1.01

    Лучше юзать связки HeapCreate - HeapDestroy, + HeapAlloc, HeapReAlloc, HeapSize, HeapFree и даже HeapValidate есть.
     
  8. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Вот еще простой способ:
    Код (Text):
    1. AllocateHeap proc near
    2.     arg_0  = dword ptr  4
    3.        assume fs:nothing
    4.        mov eax,fs:18h
    5.        push [esp+arg_0]
    6.        mov eax,[eax+30h]
    7.        push 0
    8.        push dword ptr [eax+18h]
    9.        call RtlAllocateHeap
    10.        retn 4
    11. AllocateHeap endp
    12.  
    13. FreeHeap proc near
    14.      arg_0  = dword ptr  4
    15.        assume fs:nothing
    16.        mov eax,fs:18h
    17.        push [esp+arg_0]
    18.        mov eax,[eax+30h]
    19.        push 0
    20.        push dword ptr [eax+18h]
    21.        call RtlFreeHeap
    22.        retn 4
    23. FreeHeap endp
    24.  
    25. push 1024
    26. call AllocateHeap
    27. mov hMemory,eax
    28.  
    29. ;----
    30.  
    31. push hMemory
    32. call FreeHeap
     
  9. dgs

    dgs New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2008
    Сообщения:
    434
    М-да, а я то функции правильно писал, я их не правильно вызывал... Ну, это я так пример привел, кому интересно...

    До:
    Код (Text):
    1.                 stdcall MemoryInit, [name#.table], [name#.LenTable]
    2.                 mov     [name#.table+4], eax
    После:
    Код (Text):
    1.                 stdcall MemoryInit, name#.table, [name#.LenTable]
    2.                 mov     [name#.table+4], eax
    Странно давно не кодил уже наверно больше полгода, даже какое то чувство появилось, что мир изменился... И ответный вопрос в придачу для программистов средней руки (не буду беспокоить мастеров), а смогу ли я создать без эксептионс 2000 куч с помощью HeapCreate? Просто помнится, что default process heap 1 мб, а если больше кучу делать все получиться?
     
  10. lamer2k

    lamer2k New Member

    Публикаций:
    0
    Регистрация:
    14 май 2006
    Сообщения:
    88
    MSDN - послезная штука.
    HeapCreate смотрим.

    синтаксис:

    далее читаем что по размерам:

     
  11. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Nt* это хэндлер в ядре для соотв. Zw*. В юзермоде Nt* просто мост на Zw*, Zw* и юзаем. Забудь про хип. Юзай это либо секции.
     
  12. lamer2k

    lamer2k New Member

    Публикаций:
    0
    Регистрация:
    14 май 2006
    Сообщения:
    88
    2CrystalIC, безсмысленно использовать NtAllocateVirtualMemory ИМХО
     
  13. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Думаешь ?
    ЗЫ Смени ник, потом думай.
     
  14. dgs

    dgs New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2008
    Сообщения:
    434
    Глобал рушиться при увеличении размера блока, буду пробовать Хеап, в противном случае NtAllocateVirtualMemory... Завтра скажу результаты...

    А какие функции выделения памяти выделяют, точно запрошенному размеру, ну типа без выравнивания на 64?

    PS/ еп*аный FASM...
     
  15. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    dgs
    Пора бы всё таки запомнить (тема тут тыщу раз поднималась), что Global/LocalAlloc и флаги GMEM_MOVEABLE/GMEM_FIXED это наследие win16 с её общим на все программы адресным пространством и сохранилось только для совместимости доисторическим наследием. Современные win не делят память на Global/Local и никакие блоки по своей иннициативе не перемещают, даже если они GMEM_MOVEABLE, ибо при раздельном адресном пространстве процессов это уже не актуально. Вместо них теперь HeapAlloс, которая для каши из мелких блоков. Если же нужен большой блок памяти или есть желание самому управлять своей кашей из блоков, тогда VirtualAlloc.
    Создавать свою дополнительную Heap нужно только если это действительно нужно (что вообще-то оооочень редко) в подавляющем большинстве программ правильно использовать GetProcessHeap, особенно бегиннерсам.
    Во всякие Zw* Nt*, rtl* не лезь пока они действительно не понадобятся.

    Если нужна надёжная (в смысле предсказуемая) работа с мелкими блоками, выделяй большой блок через VirtualAlloc и дели его сам как тебе надо, Heap это для каши из блоков, для которых не принципиально где и как они расположены, на то она и куча :)
     
  16. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    "Они образованность свою показать хочут, вот и говорят о непонятном" (с)

    На каждый чих виртуальную память будем выделять, да? С гранулярностью в 4К (размер страницы, если точнее), да?
    Дерево из десяти тысяч объектов, каждый из которых размером 8 байт, при таком раскладе займет 400М, нормально, да?
     
  17. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Ursus
    О чём ты, ничего показать не хочу, загляни внутрь функций управления хипами, тогда увидишь что реально понять сложно. Никогда не видел отладочный останов изза "Heap corrupt detected", или необработанное исключение при перечислении куч ?
    Хип слишком сложный и как следствие не стабильный механизм. Нужно на первый чих выделить память а часть зарезервировать. Так делол бы я, впрочем мне всёравно, это был только совет.
     
  18. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Ну это вообще пЪять! :)
    Компьютер слишком сложный, и поэтому нестабильный, и ну его нафиг! На счётах (деревянных) надо считать, господа, на счётах!
     
  19. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Y_Mur
    Лично мне, как бегиннерсу, всегда нравилась возможность уничтожить всю свою кучу целиком после работы, чем освобождать каждый участочек по 8-10 байт из дефолтной.
    Как пример - собрать список файлов в строку. Пока проходимся по FindNextFile, выделяем по чуть-чуть из кучи, составляя связный список. А потом всё, что насобирали, переписываем в сплошную область памяти. Так вот ИМХО после сбора списка легче удалить всю кучу сразу, чем каждое имя файла по одному из дефолтной кучи удалять.
     
  20. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    А нахрена? Проще же вообще рестартануть процесс - и всех делов, все лишние ресурсы освобождены!

    А если серьезно, то описанный тобой подход работает лишь в простейшем случае, когда память выделяется для примитивных данных. В реальности же память чаще выделяется под объекты. И если удалить весь хип, то деструкторы этих объектов вызваны не будут, что может привести к самым неожиданным багам :)