2014-01-02 6 views
0

При попытке выяснить, почему одно из наших новых приложений терпит крах, я преследовал утечки памяти в Delphi.Утечка памяти при назначении записи

Я подключил последнюю версию FastMM и проработал результаты, но меня смущает следующее, которое я сварил до голых костей ради краткости.

У нас есть запись с двумя строковыми полями. Они назначаются из двух блоков TEdit, и в то же время мы записываем данные в TListView. Вот ключевой код:

procedure TForm1.SetAssignment; 
var 
    tp: TestPointer; 
    SourceTable, SourceColumn: string; 
    LI: TListItem; 
begin 
    SourceTable := Edit1.Text; 
    SourceColumn := Edit2.Text; 
    LI := lvTest.Items.Add; 
    LI.Caption := SourceTable; 
    LI.SubItems.Add(SourceColumn); 
    new(tp); 
    // Leak occurs here 
    tp^.SourceTable := SourceTable; 
    tp^.SourceField := SourceColumn; 
    // No leak if preceding lines are ommitted 
    TestList.Add(tp); 
end; 

Проблема, кажется, с со значением SourceTable/SourceColumn, или с ф ^. значения.

TList должным образом очищается, когда мы совершенно: если мы прокомментируем присвоения tp^.SourceTable/tp^.SourceField, тогда утечки памяти не произойдет.

Может быть, это только потому, что Новый год, но я не могу видеть, как я выпускаю SourceTable/SourceColumn ...

+5

Пожалуйста, покажите код для очистки 'TList'. Вероятно, вы НЕ завершаете каждую запись, поэтому компилятор освобождает своих членов String. Вы можете альтернативно установить каждый член String '' ''перед тем, как освободить саму запись. –

+1

Также см. [Финализация] (http://docwiki.embarcadero.com/Libraries/XE5/en/System.Finalize) –

+1

«TList правильно очищается» - если вы не можете найти ошибку, нет смысла в слепо веря своим словам и предположениям. сам факт ошибки доказывает, что одно из ваших предположений неверно. Итак - «сомневайтесь во всем» (c) Декарт. Вы процитировали код из 'new (tp);' до 'TestList.Add (tp);' - no, пожалуйста, покажите противоположную сторону от 'undo TestList.Add (tp);' to 'undo new (tp)' и позвольте нам мы выглядим, если код «правильно» со свежими глазами. Ваш код не «правильно» - он течет. Это тот факт, что нужно начинать копаться. Итак - покажите, пожалуйста, фактический код. –

ответ

3

Я ожидаю, что ваш моются код вызывает FreeMem, а не Dispose на указателе. Это единственное, что я могу себе представить, что есть эти симптомы. FreeMem просто освобождает память, но Dispose также дорабатывает содержимое перед освобождением.

Когда вы вызываете Dispose, вы должны указать правильно напечатанный указатель. Для вашего случая вы должны передать TestPointer для Dispose.