Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Утечка AnsiString [D7, XP]


Страницы:   1 2

kami ©   (2008-10-11 01:18:00) 

Проверяю с помощью FastMM.

Есть структура, которая передается в конструктор объекта. Структура содержит 2 поля типа string:
TSomeRecord=packed record
 SomeField1:integer;
//.........
 SomeFieldx:string;
 SomeFieldy:string;
end;
//....................
constructor TDataObject.Create(Header: TSomeRecord; Data: TStream);
begin
 FHeader:=Header;
 //..................
end;

Объект уничтожается штатно (проверено, оттрассировано).
Самое интересное - при создании максимально упрощенного примера утечек не происходит... Сильно подозреваю, что это вызывано тем, что объект создается в одном потоке, а уничтожается в другом (потоки - наследники TThread). Понимаю, что это не есть сильно правильно, но структуру программы поменять не получится :(.
Что можно сделать для ликвидации утечек?

P.S. Чуть не забыл - лог FastMM:
Блок памяти был выделен и не освобожден. Размер: 20

Трассировка стека при выделении блока (вхождения):
40427D [System][@NewAnsiString]
404210 [System][@LStrAsg]
404EDD [System][@CopyRecord]
462A55 [F:\...\uDataObject.pas][uDataObject][TDataObject.Create][110]
463E63 [F:\...\uDataThread.pas][uDataThread][TData.Send][439]
4678CA [Unit1.pas][Unit1][TForm1.Button4Click][119]
4342DA [Controls][TControl.Click]
42CB61 [StdCtrls][TButton.Click]
42CC55 [StdCtrls][TButton.CNCommand]


oxffff   (2008-10-11 19:50:00) [21]


> kami ©   (11.10.08 19:31) [10]


А как ты делаешь вывод, что именно в этой строке утечка памяти?
Твои умозаключения на чем построены?

FHeader := Header соответствует
404EDD [System][@CopyRecord]
судя по названию


kami   (2008-10-11 19:31:00) [22]

oxffff ©   (11.10.08 12:47) [9]
> А как ты сделал вывод, что проблема именно в TSomeRecord?

Лог FastMM:
462A55 [F:\...\uDataObject.pas][uDataObject][TDataObject.Create][110]
На строке 110 этого модуля:
FHeader := Header;
Все, что вызвано ранее - транзит между модулями до достижения непосредственно конструктора объекта.
Palladin ©   (11.10.08 12:21) [7]
> Компилятор не будет этого делать, при штатной работе с записями
> (не указателями на запись, а с ними самими)

Не пользуюсь указателями в этом и близлежащих классах. Реальный код выкладывать - слишком много, сейчас пытаюсь минимизировать его до разумного уровня, но пока не очень получается...


oxffff   (2008-10-11 12:47:00) [23]


> kami ©   (11.10.08 01:18)  


А как ты сделал вывод, что проблема именно в TSomeRecord?
Может не освобождается что-то другое?
Например технически очень просто организовать финализацию объекта, но освобождение памяти под объекта сделать позже.


Anatoly Podgoretsky   (2008-10-11 12:22:00) [24]

Стучит, стучит в подвале.


Palladin   (2008-10-11 12:21:00) [25]


> Гхм... разве что это сделал сам компилятор.

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


kami   (2008-10-11 12:18:00) [26]

> Германн ©   (11.10.08 01:44) [1]
> Ну а что ты хочешь получить в ответ?
> " у тебя ошибка в 17-й строке
> Реальный ответ и реальную помощь в сложных ситуациях можно
> получить только дав реальный код.


Это я прекрасно понимаю. Думал, может кто сталкивался с подобным. Минимальный код, дающий ошибку...попробую

> Юрий Зотов ©   (11.10.08 08:47) [2]
FHeader.SomeFieldx := '';

Пробовал изначально. Не помогает.

>Юрий Зотов ©   (11.10.08 10:44) [4]
> если память под record была выделена через GetMem, а освобождена
> через FreeMem, то финализировать надо ручками.

Гхм... разве что это сделал сам компилятор. В этом случает GetMem|AllocMem даже близко не пахнет.
Хорошо, я понял, что нужен работающий (вернее, утекающий) код. Попробую его сообразить.


> Palladin ©   (11.10.08 10:59) [5]
>если это так, то, понятное дело - автор ССЗБ
.
Спасибо на добром слове :) Отрицать не буду, вполне возможно :)


Palladin   (2008-10-11 10:59:00) [27]


> если память под record была выделена через GetMem, а освобождена
> через FreeMem

если это так, то, понятное дело - автор ССЗБ...


Юрий Зотов   (2008-10-11 10:44:00) [28]

> Palladin ©   (11.10.08 10:35) [3]

Насколько я понимаю, если память под record была выделена через GetMem, а освобождена через FreeMem, то финализировать надо ручками.

Во всяком случае, я бы попробовал. Написать деструктор - минута, а потом можно помотреть, что покажет FastMM.


Palladin   (2008-10-11 10:35:00) [29]


> Юрий Зотов ©   (11.10.08 08:47) [2]

в деструкторе вызываeтся FinalizeRecord, думаю причина в другом... реальный код нужен...

аффтору рекомендую постепенно упрощать модель пока не будет все в порядке, потом глянуть что же упростил...


Юрий Зотов   (2008-10-11 08:47:00) [30]

destructor TDataObject.Destroy;
begin
 FHeader.SomeFieldx := '';
 FHeader.SomeFieldy := '';
 inherited
end;


Германн   (2008-10-11 01:44:00) [31]


> Самое интересное - при создании максимально упрощенного
> примера утечек не происходит...

Ну а что ты хочешь получить в ответ?
" у тебя ошибка в 17-й строке, которая в сабже представлена как "..."?
Не, ну можно ещё припомнить "подземный стук", но это не меняет сути.
Реальный ответ и реальную помощь в сложных ситуациях можно получить только дав реальный код. Код, который даёт ошибку. И который можно воспроизвести на любом компе, на котором установлена  та версия Дельфи.
,


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо