![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Утечка AnsiString [D7, XP]
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-й строке, которая в сабже представлена как "..."?
Не, ну можно ещё припомнить "подземный стук", но это не меняет сути.
Реальный ответ и реальную помощь в сложных ситуациях можно получить только дав реальный код. Код, который даёт ошибку. И который можно воспроизвести на любом компе, на котором установлена та версия Дельфи.
,