Утечка памяти в Ada.Strings. Unbounded? - PullRequest
       55

Утечка памяти в Ada.Strings. Unbounded?

2 голосов
/ 09 сентября 2011

У меня странная утечка памяти, похоже, что библиотечная функция to_unbounded_string протекает!

Фрагменты кода:

procedure Parse (Str    : in     String;

... делать вещи ...

declare
   New_Element : constant Ada.Strings.Unbounded.Unbounded_String :=
     Ada.Strings.Unbounded.To_Unbounded_String (Str); -- this leaks
begin

вывод valgrind:

==6009== 10,276 bytes in 1 blocks are possibly lost in loss record 153 of 153
==6009==    at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==6009==    by 0x42703B8: __gnat_malloc (in /usr/lib/libgnat-4.4.so.1)
==6009==    by 0x4269480: system__secondary_stack__ss_allocate (in /usr/lib/libgnat-4.4.so.1)
==6009==    by 0x414929B: ada__strings__unbounded__to_unbounded_string (in /usr/lib/libgnat-4.4.so.1)
==6009==    by 0x80F8AD4: syntax__parser__dash_parser__parseXn (token_parser_g.adb:35)

Где token_parser_g.adb: 35 указан выше как строка «- это утечка».

Другая информация: Gnatmake версия 4.4.5,gcc версия 4.4 valgrind версия valgrind-3.6.0.SVN-Debian, параметры valgrind -v --leak-check = полная --read-var-info = да --show-достижимая = нет

Любая помощьили понимание приветствуется,

NWS.

Ответы [ 3 ]

4 голосов
/ 09 сентября 2011

Valgrind ясно говорит, что возможно утечка памяти.Это не обязательно означает, что есть.Например, если первый вызов этой функции выделяет пул памяти, который повторно используется в течение времени жизни программы, но никогда не освобождается, Valgrind сообщит об этом как о возможной утечке памяти, даже если это не так, как этообычная практика и память будут возвращены в ОС после завершения процесса.

Теперь, если вы думаете, что существует реальная утечка памяти, вызовите эту функцию в цикле и увидите, что память продолжает расти.Если это так - подайте отчет об ошибке или, что еще лучше, попробуйте найти и устранить утечку и отправить исправление вместе с отчетом об ошибке.

Надеюсь, это поможет.

2 голосов
/ 09 сентября 2011

Пытался оставить это в комментариях, но то, что я говорил, слишком долго и начало нуждаться в форматировании.

В строковых объектах Ada обычно предполагается идеальный размер. Язык предоставляет функции для возврата размера и границ любой строки. Из-за этого обработка строк в Ada очень отличается от C, и на самом деле больше напоминает то, как вы это делаете на функциональном языке, таком как Lisp.

Но основной принцип заключается в том, что, за исключением некоторых очень необычных ситуаций, , если вы обнаружите, что используете Ada.Strings.Unbounded, вы поступаете неправильно.

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

Однако даже здесь вы должны иметь такую ​​ситуацию только в исходном буфере. Ваш вызов в вашу процедуру Parse должен выглядеть примерно так:

Ada.Text_IO.Get_Line (Buffer, Buffer_Len);
Parse (Buffer(Buffer'first..Buffer'first + Buffer_Len - 1));

Теперь внутри процедуры Parse у вас есть константа Ada идеального размера для работы. Если по какой-либо причине вам нужно вытащить сублиме, вы должны сделать следующее:

... --// Code to find start and end indices of my subslice
New_Element : constant String := Str(Element_Start...Element_End);

Если вам по какой-то причине вам не нужно делать копию этих данных, вам лучше просто найти Element_Start и Element_End и поработать с фрагментом исходного строкового буфера. Например:

if Str(Element_Start..Element_End) = "MyToken" then

Я знаю, что это не отвечает на ваш вопрос об Ada.Strings. Неограниченный, возможно, утечка. Но даже если он не протекает, этот код относительно бесполезен для машинных ресурсов (ЦП и памяти) и, вероятно, не должен использоваться для манипулирования строками, если вам действительно не нужно .

1 голос
/ 10 сентября 2011

Ограничены ли связанные строки [ed] областью действия?

Расширяя комментарии @ TED, объекты Ada.Strings.Bounded "не должны реализовываться неявными указателями и динамическим распределением«.Вместо этого максимальный размер фиксируется при создании экземпляра generic.В качестве детали реализации GNAT использует дискриминант для указания максимального размера строки и запись для хранения текущего размера и содержимого.

В отличие от Ada.Strings.Unbounded требует, чтобы «ни одно хранилище, связанное с объектом Unbounded_String, не было потеряно при назначении или выходе из области».В качестве детали реализации GNAT использует буферизованную реализацию, полученную из Ada.Finalization.Controlled.В результате память, используемая Unbounded_String, может казаться утечкой до тех пор, пока объект не будет завершен, как, например, когда код возвращается в окружающую область.

...