Новые вопросы - какая функция определяет наличие или отсутствие утечек памяти? 
Я скачал ВинАДУ, поставил, как подключить пакет, содержащий заголовки виндовых библиотек? with ADA.Windows не рабтает, нет такого пакета.
			
			1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!! 
Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.
![]() ![]()  | 
	
| TarasBer | 
                        
			
			  
			
				 Сообщение
					#1				
			 
		 | 
	
        	
        		![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация:    62           	 | 
       
			
			 Новые вопросы - какая функция определяет наличие или отсутствие утечек памяти?  
			
			Я скачал ВинАДУ, поставил, как подключить пакет, содержащий заголовки виндовых библиотек? 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 Пол: Мужской Репутация:    62           	 | 
       
			
			 > Целый пакет есть для этого: 
			
			Всё по нулям выводит, якобы я ничего не выделял и не освобождал. Total allocated bytes : 0 Хотя сделал ровно так - добавил пакет, описание переменной, инициализацию в начале, вывод в конце. > with "win32ada"; А это что за конструкция - название в кавычках? Типа заставить среду навсегда подключить набор пакетов? > P.S. Я тут задумал написать про нововведения в A2012, нужно? Ну вообще интересно, да. --------------------  | 
	
| volvo | 
                        
			
			  
			
				 Сообщение
					#4				
			 
		 | 
	
| 
        	
        		 Гость  | 
       
			
			 Цитата Типа заставить среду навсегда подключить набор пакетов? Не навсегда, а для данного проекта.Цитата Всё по нулям выводит, якобы я ничего не выделял и не освобождал. Странно... Попробовал "забыть" освободить выделенную память, меня тут же ткнули носом:А. Ну да, я забыл написать про use D_Pool... На скрине видно, как оно используется...  | 
	
| TarasBer | 
                        
			
			  
			
				 Сообщение
					#5				
			 
		 | 
	
        	
        		![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация:    62           	 | 
       
			
			 Всё равно непонятно. Как его подключить к указателю, зашитому внутрь объекта из другого пакета? Пока только приходит в голову объявить его в отельном модуле, который подключить ко всем модулям проекта. 
			
			А если мне потом понадобится его отрубить, то надо написать как-то 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 Пол: Мужской Репутация:    62           	 | 
       
			
			 > Закончил отладку (убедился, что утечек нет) - отключай 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 Пол: Мужской Репутация:    62           	 | 
       
			
			 > ("-gnateDDEBUGGING=True") 
			
			А для этих ключей можно свои имена придумывать? Например "-TestLeaks=True"? --------------------  | 
	
| volvo | 
                        
			
			  
			
				 Сообщение
					#10				
			 
		 | 
	
| 
        	
        		 Гость  | 
       
			
			 Разумеется. Ключ -gnateD создает символ для условной компиляции (это аналог Паскалевского ключа /D). Как назовешь - так и будет. Напиши -gnateDTestLeaks=True и будет тебе счастье... 
			
			
					
		 | 
	
| TarasBer | 
                        
			
			  
			
				 Сообщение
					#11				
			 
		 | 
	
        	
        		![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация:    62           	 | 
       
			
			 В общем, заставить определять некорректные выражения и заставить освобождать память и для них, при возникновении исключений, оказалось непросто. Невозврат out-параметра при исключении изрядно меня напряг, заставив многое усложнить. 
			
			(проще было бы все созданные по пути деревья в отдельный список заносить, и освобождать по списку, чтобы не париться с рекурсивными выходами). Новая версия:  
 TEST.rar ( 10.24 килобайт )
Кол-во скачиваний: 534добавлена фича - если записать в ряд несколько выражений, то считаются все: Код 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 Пол: Мужской Репутация:    62           	 | 
       
			
			 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 Пол: Мужской Репутация:    62           	 | 
       
			
			 > Можешь, конечно, написать, только компилироваться оно не будет. 
			
			Вот и я о том же. А ведь если б разрешили, то такое заворачивать можно было бы! Сообщение отредактировано: TarasBer - --------------------  | 
	
| 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 Пол: Мужской Репутация:    62           	 | 
       
			
			 А как сделать так, чтобы код между   
			
			#if Test_Leaks и #end if; не выполнялся? Я убрал & ("-gnateDTest_Leaks=True") , не помогло. Закрыл среду, удалил exe, открыл среду, всё равно не помогло. --------------------  | 
	
| volvo | 
                        
			
			  
			
				 Сообщение
					#19				
			 
		 | 
	
| 
        	
        		 Гость  | 
       
			
			 & ("-gnateDTest_Leaks=False") 
			
			
					
		 | 
	
| TarasBer | 
                        
			
			  
			
				 Сообщение
					#20				
			 
		 | 
	
        	
        		![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация:    62           	 | 
       
			
			 Тоже не помогло. Главное, я нажимаю ctrl+F9, а программа пересобирается мгновенно, будто ей не надо все модули из-за новой директивы перекомпилировывать. 
			
			--------------------  | 
	
![]() ![]()  | 
	
 
  | 
		Текстовая версия | 4.11.2025 20:49 |