[Plugin] Dynamic memory v1.2.1
#1

Мой первый плагин

Знаю, что подобные поделки уже существуют, но все же....

Данный плуг предназначен для управления (выделения/копирования/освобождения) динамической памятью напрямую через скрипты. Это удобно, например, если вы имеете дело с очень большими объемами данных, но не можете/не хотите иметь при этом *.amx чудовищно огромных размеров.

Выглядит это слегка коряво, по сравнению, скажем, с Cи (все данные, помещаемые в динамический "буфер", нельзя подать напрямую какой-нибудь стандартной функции, нужно сначала извлечь их во временный массив; указателей и подавно нет). Однако более удобной/гибкой реализации мне в голову, к сожалению, пока не пришло... так что если у вас есть предложения по улучшению/ усовершенствованию плагина - пишите!


Функции

Есть всего семь функций. Каждая оперирует с переменным типа Pointer: (указатель), которые на самом деле являются адресами выделенных участков памяти. Хотя звучит все просто, на самом деле не любой указатель можно передать в качестве аргумента (в целях безопасности), а лишь указывающий на один из выделенных блоков. Все они хранятся в специальной структуре (АВЛ-дерево), поиск по которой происходит довольно быстро, так что данные меры не сильно влияют на производительность.


pawn Код:
/* Выделяет участок динамической памяти определенного размера.
 *
 * Параметры:
 *  size - рамер блока (в ячейках, не в байтах)
 *  clear - если true, каждая ячейка выделенного участка будет заполнена указанным значенем.
 *  value - значение, которым необходимо заполнить все ячейки.
 *  
 * Возвращает:
 *  Указатель на выделенный блок или NULL в случае ошибки (например, не хватило памяти).
 */

native Pointer:mem_allocate(size, bool:clear = false, value = 0);


/* Изменяет размер выделенного участка памяти.
 *
 * Параметры:
 *  ptr   - указатель.
 *  new_size - новый размер.
 *  
 * Возвращает:
 *  true при отсутствии ошибок, иначе - false.
 */

native bool:mem_resize(Pointer:ptr, new_size);


/* Освобождает память.
 *
 * Параметры:
 *  ptr - указатель на освобождаемый блок.
 *  
 * Возвращает:
 *  true при отсутствии ошибок, иначе - false.
 *
 * Замечание: после вызова данной функции значение ptr недействительно
 *      и не может быть больше использовано, т.к. указывает на
 *      несуществующий блок.
 */

native bool:mem_free(Pointer:ptr);


/* Копирует содержимое блока в указанный массив.
 *
 * Параметры:
 *  source - указатель на копируемый.
 *  dest  - буфер, в который производится копиррование.
 *  start - индекс первой копируемой ячейки (ее номер в блоке).
 *  count - количество копируемых ячеек.
 *  
 * Возвращает:
 *  Число копированных элементов.
 */

native mem_get(Pointer:source, dest[], start = 0, count = sizeof(dest));


/* Копирует содержимое массива в указанный блок.
 *
 * Параметры:
 *  dest  - указатель на блок, в который записывается массив.
 *  source - массив, элементы которого копировать.
 *  start  - индекс первой копируемой ячейки (ее номер в блоке).
 *  count - количество копируемых ячеек.
 *  
 * Возвращает:
 *  Число копированных элементов.
 */

native mem_set(Pointer:dest, const source[], start = 0, count = sizeof(source));


/* Копирует содержимое одного блока в другой.
 *
 * Параметры:
 *  source - указатель на копируемый блок.
 *  dest   - указатель на второй блок, в который будет производена запись.
 *  
 * Возвращает:
 *  Число копированных элементов.
 */

native mem_copy(Pointer:source, Pointer:dest);


/* Узнает размер ранее выделенного участка.
 *
 * Параметры:
 *  ptr - указатель на блок.
 *  
 * Возвращает:
 *  Размер блока.
 */

native mem_size(Pointer:ptr);


Скачать

Как скомпилировать

  • Linux

    Перейдите в корень папки с проектом и наберите в терминале make


  • Windows
    • Visual Studio

      Просто откройте проект и скомпилируйте, .dll появится в папке Release. Проект был создан в VS2010 Express, может не работать на старых версиях (не проверено).


    • MinGW

      Запустите командную оболочку Windows (Пуск -> Выполнить -> cmd), перейдите в папку проекта и выполните mingw32-make -f Makefile.mingw


Список изменений

pawn Код:
[13/04/2010]: v1.2.1
    - Добавлена функция mem_size

 [12/04/2010]: v1.2
    - Изменены параметры некоторых функций
    - Исправлены ошибки в процедурах mem_get/set/copy
    - В инклуд добавлен удобный макрос, позволяющий выделять память прямо при объявлении указателя, без явного вызова mem_allocate

 [11/04/2010]: v1.1
    - Исправлен баг в mem_allocate, привыодивший к ошибке "out of memory"
    - Исправлено падение сервера при вызове mem_free для некорректного адреса
    - Исправлены мелкие недоработки при выводе сообщений об ошибках

 [11/04/2010]: v1.0
    - Первая версия
Reply
#2

скрипт в пример кинь, может найду применение.
Reply
#3

Толкьо что обнаружены небольшие косяки, идет доработка... Пример будет позже

Ed: исходный код и файлы для Windows перезалиты, Linux-версия будет в скором времени тоже
Reply
#4

мм, а через new никак не получится?
или простенькую систему деревьев, но не такую сложную...
примеры можно посмотреть тут:
http://shatalov.su/algorithms/tree.php
http://shatalov.su/algorithms/list_1.php
http://shatalov.su/algorithms/list_2.php
Reply
#5

Ну дак там и так дерево
http://ru.wikipedia.org/wiki/%D0%90%...B5%D0%B2%D0%BE
Reply
#6

Нужная весч (: зачот

Лично мне-то сразу стало ясно как использовать. Но для тех, кто не понял нужны примеры и, хотя бы, предполагаемые области применения. Так скать, если юзер будет знать, где это применить, респект гарантирован (:
Reply
#7

молодец Zeex
Reply
#8

В результате тестов сегодня были обнаружены серьезные недоработки в механизме копирования/записи блоков... скоро выйдет новая версия
Reply
#9

Ну, яростно требую мануала с примерами по этой штуке. Например, как в выделенную память записать массив (строку с символами) или значение типа float. Респекты уже.
Reply
#10

Обновление! Подробности в чейнджлоге

Также в шапку добавлена ссылка на небольшой пример
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)