![]() |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
![]() ![]() |
![]() |
TarasBer |
![]()
Сообщение
#1
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Новые вопросы - какая функция определяет наличие или отсутствие утечек памяти?
Я скачал ВинАДУ, поставил, как подключить пакет, содержащий заголовки виндовых библиотек? with ADA.Windows не рабтает, нет такого пакета. -------------------- |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Цитата какая функция определяет наличие или отсутствие утечек памяти? Целый пакет есть для этого:with GNAT.Debug_Pools; use GNAT.Debug_Pools;После окончания работы программы получаешь полный список: сколько выделил памяти, сколько освободил, где не освободил... Цитата Я скачал ВинАДУ, поставил, как подключить пакет, содержащий заголовки виндовых библиотек? with ADA.Windows не рабтает, нет такого пакета. Правильно. Его и не было.with Win32. { тут может быть много дочерних пакетов } Но сначала открой GPR-файл, и самой первой строкой добавь with "win32ada";, после чего перезагрузи проект. А еще лучше - сделать это без загруженной IDE. Я всегда так делаю - создаю новый проект, выхожу из IDE, правлю GPR, и загружаю среду заново (ну, или вообще набираю GPR вручную. Там всего - то 10 строк нужно)... Если устанавливал win32ada-gplXXXX.exe и ошибок при установке не было - то все должно завестись. P.S. Я тут задумал написать про нововведения в A2012, нужно? |
TarasBer |
![]()
Сообщение
#3
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> Целый пакет есть для этого:
Всё по нулям выводит, якобы я ничего не выделял и не освобождал. Total allocated bytes : 0 Хотя сделал ровно так - добавил пакет, описание переменной, инициализацию в начале, вывод в конце. > with "win32ada"; А это что за конструкция - название в кавычках? Типа заставить среду навсегда подключить набор пакетов? > P.S. Я тут задумал написать про нововведения в A2012, нужно? Ну вообще интересно, да. -------------------- |
volvo |
![]()
Сообщение
#4
|
Гость ![]() |
Цитата Типа заставить среду навсегда подключить набор пакетов? Не навсегда, а для данного проекта.Цитата Всё по нулям выводит, якобы я ничего не выделял и не освобождал. Странно... Попробовал "забыть" освободить выделенную память, меня тут же ткнули носом:![]() А. Ну да, я забыл написать про use D_Pool... На скрине видно, как оно используется... |
TarasBer |
![]()
Сообщение
#5
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Всё равно непонятно. Как его подключить к указателю, зашитому внутрь объекта из другого пакета? Пока только приходит в голову объявить его в отельном модуле, который подключить ко всем модулям проекта.
А если мне потом понадобится его отрубить, то надо написать как-то D_Pool: Standart_Pool ? -------------------- |
volvo |
![]()
Сообщение
#6
|
Гость ![]() |
Цитата А если мне потом понадобится его отрубить , то не надо его подключать. Это только средство отладки. Закончил отладку (убедился, что утечек нет) - отключай GNAT.Debug_Pools и все use D_Pool.Цитата Как его подключить к указателю, зашитому внутрь объекта из другого пакета? Пока только приходит в голову объявить его в отельном модуле, который подключить ко всем модулям проекта. Правильно. С учетом того, что использование Use невозможно для типов, описанных в другом пакете - это единственный способ: везде, где у тебя есть динамическое выделение памяти и ее удаление (через Unchecked_Deallocation) добавить строку, указывающую пул для access-типа. Ну, а чтоб она была одна и та же - описать ее в отдельном пакете.Вот чего в Аде нет ( напрямую нет, но можно имитировать: Conditional Compilation ) - это условной компиляции, так что когда тебе понадобится убрать отладку - придется еще раз пройти по всем пакетам, и убрать назначение для Storage_Pool. Можно также воспользоваться The gnatmem tool |
TarasBer |
![]()
Сообщение
#7
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> Закончил отладку (убедился, что утечек нет) - отключай GNAT.Debug_Pools и все use D_Pool.
Жесть какая... А переопределить в том модуле D_Pool на стандартный можно, это какая конструкция делает? > Вот чего в Аде нет - это условной компиляции А хоть введут? Блоки вида if true then... - это покрывает только один случай применения условной компиляции. -------------------- |
volvo |
![]()
Сообщение
#8
|
Гость ![]() |
Цитата А переопределить в том модуле D_Pool на стандартный можно, это какая конструкция делает? Можно, но это плохая идея. Дело в том, что глобальные ссылочные типы используют один пул (из пакета System.Pool_Global), локальные - другой (из System.Pool_Local). Что, будешь переопределять всё в один? Я бы не делал этого.Цитата А хоть введут? Блоки вида if true then... - это покрывает только один случай применения условной компиляции. Ну я ж написал, что нет в явном виде. Используй gnatprep - это несложно:#if DEBUGGING(аналогичные #if/#end if; во всех файлах, где добавляется тестирование), потом открываешь GPR-файл, и ищешь там описание пакета Compiler. У меня оно, скажем, выглядит так: package Compiler is добавляешь сюда же, в дефолт-опции, еще и предварительную обработку процессором: package Compiler is Сохраняешь файл и полностью пересобираешь проект. Когда отладишь - снова зайдешь сюда, поменяешь в определении ключа True на False, и опять пересоберешь - отладочные строки не будут компилироваться... |
TarasBer |
![]()
Сообщение
#9
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> ("-gnateDDEBUGGING=True")
А для этих ключей можно свои имена придумывать? Например "-TestLeaks=True"? -------------------- |
volvo |
![]()
Сообщение
#10
|
Гость ![]() |
Разумеется. Ключ -gnateD создает символ для условной компиляции (это аналог Паскалевского ключа /D). Как назовешь - так и будет. Напиши -gnateDTestLeaks=True и будет тебе счастье...
|
TarasBer |
![]()
Сообщение
#11
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
В общем, заставить определять некорректные выражения и заставить освобождать память и для них, при возникновении исключений, оказалось непросто. Невозврат out-параметра при исключении изрядно меня напряг, заставив многое усложнить.
(проще было бы все созданные по пути деревья в отдельный список заносить, и освобождать по списку, чтобы не париться с рекурсивными выходами). Новая версия: ![]() добавлена фича - если записать в ряд несколько выражений, то считаются все: Код Input expression or "exit": sin(pi/3) cos(pi/3) sin(pi/3) = 8.66025403784438647E-01 cos(pi/3) = 5.00000000000000000E-01 (определять конец текущего выражения тоже вопрос отдельный, короче 95% времени я не выражение разбирал, а определял некорректности, а сам разбор тривиален) -------------------- |
volvo |
![]()
Сообщение
#12
|
Гость ![]() |
Ну, в принципе все нормально. Только непонятно, почему ты оставил вот такие повторы:
function Div(Args: Vector) return F80 is ? То же самое касается и умножения/сложения всех элементов вектора. Это ж одинаковые действия. Зачем дженерики тогда? Делаем так: generic with function F(Left, Right : F80) return F80; Еще не совсем понял, почему в Lib_Add_Funcs (при добавлении поддерживаемых функций) ты добавляешь Summ'access, вместо того, чтобы напрямую добавить Add'Access? Зачем вообще этот переходник Summ нужен? Закомментировал его, вроде и без него все нормально. Или я чего-то не увидел? Prod -> Mul тоже можно напрямую заменить... |
TarasBer |
![]()
Сообщение
#13
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Summ и Prod пока действительно не нужны. Это я добавил чтобы было отдельно для оператора и отдельно для функции. Ну мало ли в будущем мне понадобится ещё какой-нибудь контроль, и в Add (для оператора) я допишу "аргументов должно быть ровно два". Правда, тогда придётся наоборот вызывать Summ из Add.
Кстати, я вот хотел вместо function Exp is new TF(Exp); Add_Func("exp", "Экспонента", Exp'access); написать Add_Func("exp", "Экспонента", new TF(Exp)'access); Мне кажется, что это что-то уже близкое к лямбдам. > Зачем дженерики тогда? Делаем так: Для функций я догадался до генериков. Для операторов - нет, исправлю. Кстати, для них можно же написать сразу function Div is new TwoParams ("/"); function Pow is new TwoParams ("**"); ? -------------------- |
volvo |
![]()
Сообщение
#14
|
Гость ![]() |
Цитата Кстати, для них можно же написать сразу Ну да, и так тоже можно...Цитата Add_Func("exp", "Экспонента", new TF(Exp)'access); Можешь, конечно, написать, только компилироваться оно не будет. Ада запрещает in-place инстанциацию дженериков. Инстанциация должна проводиться там, где допустимо описание новой подпрограммы. В выражении это недопустимо. |
TarasBer |
![]()
Сообщение
#15
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> Можешь, конечно, написать, только компилироваться оно не будет.
Вот и я о том же. А ведь если б разрешили, то такое заворачивать можно было бы! Сообщение отредактировано: TarasBer - 8.02.2011 15:45 -------------------- |
volvo |
![]()
Сообщение
#16
|
Гость ![]() |
Хм... А чего ты вручную организуешь циклы по контейнерам, вместо того ,чтоб воспользоваться готовыми? Вот тут, например:
Цитата procedure Del_Tree(T: in out aFunc_Tree) is Да и еще я где-то видел цикл по всему контейнеру... Можно же сделать так: procedure Del_Tree(T: in out aFunc_Tree) is Почему T := null можно не делать? Это будет гарантированно сделано в Unchecked_Deallocation: Цитата(Ada RM 13.11.2) Given an instance of Unchecked_Deallocation declared as follows: procedure Free is new Ada.Unchecked_Deallocation(object_subtype_name, Procedure Free has the following effect: 1. After executing Free(X), the value of X is null. 2. Free(X), when X is already equal to null, has no effect. |
-TarasBer- |
![]()
Сообщение
#17
|
Гость ![]() |
> Да и еще я где-то видел цикл по всему контейнеру...
Кажется в том месте, где я перегонял массив в вектор? Я ещё спрашивал, нет ли готового метода. Ну и ещё в Adjust цикл по контейнеру для копирования. > Можно же сделать так: Ну буду знать. |
TarasBer |
![]()
Сообщение
#18
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
А как сделать так, чтобы код между
#if Test_Leaks и #end if; не выполнялся? Я убрал & ("-gnateDTest_Leaks=True") , не помогло. Закрыл среду, удалил exe, открыл среду, всё равно не помогло. -------------------- |
volvo |
![]()
Сообщение
#19
|
Гость ![]() |
& ("-gnateDTest_Leaks=False")
|
TarasBer |
![]()
Сообщение
#20
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Тоже не помогло. Главное, я нажимаю ctrl+F9, а программа пересобирается мгновенно, будто ей не надо все модули из-за новой директивы перекомпилировывать.
-------------------- |
![]() ![]() |
![]() |
Текстовая версия | 17.06.2025 21:52 |