![]() |
String freigeben nur wo?
Mein Problem ist leider immer noch nicht gelöst. :oops:
EurekaLog! Zitat:
FBuffin Wenn ich im Dialog von EurekaLog doppelkicke dann geht er mir in diese Zeile.
Delphi-Quellcode:
Das Problem ist nur, ich weis nicht wo ich ihn freigeben soll.
try
try while not eof(ParseFile) do begin ReadLN(ParseFile, sBuffer); AppendToLinkedList(nReading, sBuffer); // sBuffer soll einen Memoryleak produzieren. inc(nReading); end; except raise Exception.Create(SysErrorMessage(GetLastError)); end; finally nReading := 0; CloseFile(ParseFile); end; Theoretisch würde ich es so machen.
Delphi-Quellcode:
Nur dann lösche ich den String im Array dieser ist dann auch '' obwohl ich den String erst nach der Übergabe lösche.
while not eof(ParseFile) do
begin ReadLN(ParseFile, sBuffer); AppendToLinkedList(nReading, sBuffer); // sBuffer soll einen Memoryleak produzieren. inc(nReading); // String freigeben nachdem er übergeben wurde ZeroMemory(Pointer(sBuffer), Length(sBuffer) * SizeOf(Char)); sBuffer := ''; end;
Delphi-Quellcode:
Keine Ahnung wo ich den String sonst freigeben soll wenn nicht an angezeigter Position.
procedure AppendToLinkedList(nReading: Integer; sBuffer: string);
begin New(FPBuffer); if nReading = 0 then Begin New(FToPBuffer); LineStart := FToPBuffer; LineStart^.Nr := 0; end; FPBuffer^.Nr := nReading; FPBuffer^.Str := sBuffer; //<< der ist dann nachdem löschen von sBuffer leer LineStart^.Max := FPBuffer^.Nr; FToPBuffer^.Ptr := FPBuffer; FToPBuffer := FPBuffer; end; Edit: Hier das gleiche!
Delphi-Quellcode:
siehe Shot.. Doppelklick auf FormatINI dann springt er in diese Zeile.
procedure FormatINI(Filename: string);
var sBuffer: string; ParseFile: TextFile; StringList: TStringList; StringParse: string; procedure AppendToLinkedList(nReading: Integer; sBuffer: string); begin New(FPBuffer); if nReading = 0 then Begin New(FToPBuffer); LineStart := FToPBuffer; LineStart^.Nr := 0; end; FPBuffer^.Nr := nReading; FPBuffer^.Str := sBuffer; LineStart^.Max := FPBuffer^.Nr; FToPBuffer^.Ptr := FPBuffer; FToPBuffer := FPBuffer; end; begin StringList := TStringList.Create; Assignfile(ParseFile, Filename); reset(ParseFile); try try while not eof(ParseFile) do begin ReadLN(ParseFile, sBuffer); AppendToLinkedList(nReading, sBuffer); inc(nReading); end; except raise Exception.Create(SysErrorMessage(GetLastError)); end; finally nReading := 0; CloseFile(ParseFile); end; FPBuffer := LineStart; while (FPBuffer.Nr <= LineStart.Max - 1) do begin FPBuffer := FPBuffer.Ptr; StringParse := LeftTrim(FPBuffer.Str); if Length(StringParse) <> 0 then StringList.Add(FPBuffer^.Str); if FPBuffer.Nr > 0 then if LeftStr(FPBuffer^.Str, 1) = '[' then StringList.Insert(StringList.IndexOf(StringParse), ''); ZeroMemory(PWideChar(FPBuffer.Str), Length(FPBuffer.Str) * SizeOf(Char)); FPBuffer.Str := ''; end; StringList.SaveToFile(Filename); StringList.Free; Dispose(FPBuffer); FPBuffer := nil; LineStart := nil; end;
Delphi-Quellcode:
AppendToLinkedList(nReading, sBuffer);
gruss |
AW: String freigeben nur wo?
Das ZeroMemory ist hier wohl eher schädlich, da es die Referenzzählung der Strings umgeht. Ein Finalize(FPBuffer^) sollte da verträglicher sein.
Was mir auffällt ist, daß für jede Zeile im AppendToLinkedList ein New() aufgerufen wird, es aber nur ein einziges Dispose() gibt. Außerdem vermisse ich die Initialisierung von nReading mit 0. |
AW: String freigeben nur wo?
Zitat:
Zitat:
Delphi-Quellcode:
FPBuffer^.Nr := nReading;
Nun das ist schon gegeben.. nReading ist 0 beim start. Aber ich kann es noch ändern wobei ich aber denke das es nicht nötig ist. Wenn ich eine Variable als integer definiere dann ist automatisch wenn nichts anderes angegeben wird der erste wert = 0 oder liege ich da falsch? In dem Fall muss ich nReading nicht extra 0 zuweisen. Aber wenn das für dich besser ist? Kein Problem.
Delphi-Quellcode:
gruss
try
try nReading := 0; while not eof(ParseFile) do begin ReadLN(ParseFile, sBuffer); AppendToLinkedList(nReading, sBuffer); inc(nReading); end; except raise Exception.Create(SysErrorMessage(GetLastError)); end; finally CloseFile(ParseFile); end; |
AW: String freigeben nur wo?
Zitat:
|
AW: String freigeben nur wo?
Zitat:
Ich würde es aber in jedem Fall vor der while-Schleife setzen, denn dann könnte man die procedure auch mehrmals aufrufen. In dem Code habe ich sonst nur das Freigeben der Strings entfernt und eine Schleife zum Freigeben der linked List eingebaut. Vielleicht ist das MemoryLeak damit ja schon behoben.
Delphi-Quellcode:
procedure FormatINI(Filename: string);
var sBuffer: string; ParseFile: TextFile; StringList: TStringList; StringParse: string; procedure AppendToLinkedList(nReading: Integer; sBuffer: string); begin New(FPBuffer); if nReading = 0 then Begin New(FToPBuffer); LineStart := FToPBuffer; LineStart^.Nr := 0; end; FPBuffer^.Nr := nReading; FPBuffer^.Str := sBuffer; LineStart^.Max := FPBuffer^.Nr; FToPBuffer^.Ptr := FPBuffer; FToPBuffer := FPBuffer; end; begin StringList := TStringList.Create; Assignfile(ParseFile, Filename); reset(ParseFile); try try nReading := 0; while not eof(ParseFile) do begin ReadLN(ParseFile, sBuffer); AppendToLinkedList(nReading, sBuffer); inc(nReading); end; except raise Exception.Create(SysErrorMessage(GetLastError)); end; finally nReading := 0; CloseFile(ParseFile); end; FPBuffer := LineStart; while (FPBuffer.Nr <= LineStart.Max - 1) do begin FPBuffer := FPBuffer.Ptr; StringParse := LeftTrim(FPBuffer.Str); if Length(StringParse) <> 0 then StringList.Add(FPBuffer^.Str); if FPBuffer.Nr > 0 then if LeftStr(FPBuffer^.Str, 1) = '[' then StringList.Insert(StringList.IndexOf(StringParse), ''); end; StringList.SaveToFile(Filename); StringList.Free; { linked List freigeben } while LineStart <> nil do begin FPBuffer := LineStart; LineStart := FPBuffer.Ptr; { Bei Dispose kümmert sich der Compiler um das Finalize } Dispose(FPBuffer); end; { keine dangling Pointer hinterlassen } FPBuffer := nil; FToPBuffer := nil; end; |
AW: String freigeben nur wo?
danke dir Uwe..
Ich habe es vorher mal so versucht.
Delphi-Quellcode:
Ist das gleiche Ergebnis wie bei dir.
if not Assigned(FPBuffer) then
New(FPBuffer); //..... finalize(FPbuffer^); Dispose(FPBuffer); FPBuffer := nil; finalize(LineStart^); Dispose(LineStart); LineStart := nil; Ich bin darauf gekommen weil du sagtest Zitat:
Doch ist nötig ;) Deshalb nehme ich deine Lösung. Danke noch mal. Beide Varianten melden jetzt keinen Speicherleck mehr. Frage mich nur warum beim doppelklick in dem EurekaLog Dialog auf diese zeile gesprungen wird.
Delphi-Quellcode:
AppendToLinkedList(nReading, sBuffer); // sBuffer soll einen Memoryleak produzieren.
das irritiert doch etwas denn sBuffer kann ich dort nicht einfach löschen. Zitat:
gruss |
AW: String freigeben nur wo?
Zitat:
BTW, warum überhaupt eine linked List? Eine TList<PassenderRecordTyp> ist doch viel einfacher zu handhaben. Das Ptr Feld im Record wäre dann auch obsolet. Zitat:
Eurekalog kann aber nur erkennen, wo der Speicher alloziert wurde und das ist eben in dieser Zeile. |
AW: String freigeben nur wo?
Sorry Uwe war vorschnell geurteilt ;)
Habe es editiert. Zitat:
Zitat:
gruss |
AW: String freigeben nur wo?
Zitat:
|
AW: String freigeben nur wo?
Zitat:
Habe es nun mal so gemacht. Und mit Uwes Hilfe wird jetzt alles korrekt frei gegeben. Danke nochmals. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:57 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz