|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Дек 15, 2003 21:57:04 Как лучше всего выделить динамически массив. (т.е. массив на X элементов, где X-целое число, 0<X<,бесконечности) |
|
|
Дата: Дек 15, 2003 22:07:53 Одна стратегия - это malloc, потом realloc. Но не слишком-то это хорошо - происходит фрагментация памяти. Тем не менее, метод широко используется. К примеру, STL активно использует realloc. |
|
|
Дата: Дек 15, 2003 22:27:36 Как-то на работе я просматривал старый ДОС-овский код, так там у нас был странный гибрид: Массив представлен кусками по 16 элементов, причём 16-й элемент - это пойнтер на следующий кусок. Таким образом нет ре-аллокации. Доступ по индексу, правда, не удобен, надо делить индекс на 15 - доходишь до нужного куска через алгоритм связного списка, а остаток от деления - это уже прямой индекс в куске. Там ещё была функция for_each (pfn_callback, callback_parameter) - чтобы не мучиться с проходом всего массива каждый раз. |
|
|
Дата: Дек 15, 2003 22:32:38 Для этого лучше использовать VirtualAlloc - зарезервировать страницы памяти и поставить на них аттрибут PAGE_GUARD. Зарезервировать можно большой участок памяти, например 128 или 256Mb. При возникновении исключения(если элементы массива далее впишуться) надо его обрабатывать - вызывать опять VirtualAlloc для физического выделения страницы памяти(MEM_COMMIT). |
|
|
Дата: Дек 15, 2003 23:36:04 представлен кусками по 16 элементов, причём 16-й элемент - это пойнтер на следующий кусок. AsmGuru62, этот массив называется "список" :))))) Другая стратегия :))) |
|
|
Дата: Дек 15, 2003 23:42:45 dragon ...поставить на них аттрибут PAGE_GUARD Зачем? |
|
|
Дата: Дек 15, 2003 23:55:39 Затем, чтобы отлавливать исключения обращений к невыделенной памяти. Этот метод - тот же самый realloc, только фрагментации памяти не происходит, она выделяется по мере надобности и по строго по порядку. |
|
|
Дата: Дек 16, 2003 00:32:26 так а как в асме это сделать..? |
|
|
Дата: Дек 16, 2003 00:35:20 · Поправил: Toxic dragon Так исключение срабатывает только один раз. Что, каждый раз VirtualProtect вызывать? Да и кто будет к невыделенной памяти обращаться? |
|
|
Дата: Дек 16, 2003 02:45:19 а если в программе на асме сделать так: ... .data mas dd 0 .code .. mov [mas+0], dword 1 mov [mas+4], dword 2 mov [mas+8], dword 3 ... mov [mas+4000], dword 1000 ... Это будет работать? и будет ли правильно работать? |
|
|
Дата: Дек 16, 2003 03:57:08 emergenter Это будет работать? Возможно, но так делать не надо! |
|
|
Дата: Дек 16, 2003 08:53:07 emergenter Это будет работать? Я не думаю. То есть, работать-то будет(в смысле, скомпилируется), но здохнет при запуске. Сам бы мог проверить - ведь это минутное дело. |
|
|
Дата: Дек 16, 2003 12:00:44 Это будет работать. Вот допустим выделено только 4000h байт. Выполняется инструкция mov [mas+4000], dword 1000. Т.к. память не выделена, возникает исключение, при обработке которого надо будет вызвать VirtualAlloc и выделить память дальше. Резервировать сначала, чтобы адреса по порядку шли. Вот допустим так: invoke VirtualAlloc, NULL, 100000000h, MEM_RESERVE, PAGE_GUARD + PAGE_READWRITE ;резервирование 256Mb памяти. mov edi, eax ... mov [edi], 12345678h возникает исключение STATUS_GUARD_PAGE. В обработчике(надо предварительно SEH поставить) надо вызвать VirtualAlloc так(допустим в eax - адрес, по которому пытались записать или прочитать) and eax, 0FFFFF000h ;выравнивание на страницу invoke VirtualAlloc, eax, 1000h, MEM_COMMIT, PAGE_READWRITE ;Выделение памяти физически ;ну и передать управление программе на тот адрес, где исключение произошло. Вызывать VirtualProtect не нужно, т.к. PAGE_GUARD снимается при первом же исключении. Только подробно про SEH, и как информацию об исключении доставать сказать не могу, не помню. |
|
|
Дата: Дек 16, 2003 12:47:56 Если массив не очень большой (несколько Кб) да еще и локальный, можно использовать простой асмовский метод: SUB ESP, MaxElements*Element Size. :) |
|
|
Дата: Дек 16, 2003 13:00:21 Применять PAGE_GUARD в данном случае не имеет смысла. Надо просто зарезервировать кусок памяти VirtualAlloc,,MEM_RESERVE, а в обработчике SEH выделять страницу (или больше), к которой произошло обращение VirtualAlloc,,MEM_COMMIT. Только надо еще проверить попадает ли она в зарезервированный диапазон. |