Einfache Antwort (mit Beispielen):
Wenn Sie
Ergebnis tun: = vStrList
Sie zuweisen vStrList Ergebnis. In diesem Moment sind vStrList und Result SIND DAS GLEICHE! Also, in der nächsten Zeile des Codes, wenn Sie vStrList freigeben, geben Sie auch Ergebnis frei (gut, das ist nicht technisch genau, aber ich habe es verwendet, um die Erklärung einfach zu halten). Aus diesem Grund erhalten Sie einen AV, wenn Sie versuchen, das Ergebnis der Funktion zu verwenden. Das Ergebnis wurde zerstört, als Sie vStrList freigegeben haben.
So wird dies Ihr Problem lösen:
function FuncStringList:TStringList;
begin
Result := TStringList.Create;
// Do stuff with Result
// never free (here, in this function) the Result
end;
Der Anrufer von FuncStringList wird befreien "Ergebnis" HAT.
Sie nennen es wie folgt aus:
myStringList := FuncStringList;
try
myStringList.Items.Count
finally
freeandnil(myStringList); <------------- NOW you can free "Result"
end;
.
Ein weiteres Beispiel:
function makelist: tstringlist;
begin
result := tstringlist.create;
result.add('1');
result.add('2');
end;
procedure TForm1.Button_GOOD_Click(Sender: TObject);
var list : tstringlist;
begin
list := makelist;
DoStuff(list);
list.free; //ok
end;
procedure TForm1.Button_BAD_Click(Sender: TObject);
begin
listbox1.items.Assign(makelist); // <---- memory leak here because you forgot to free
end;
habe ich diese Notiz hier, bevor jemand beginnt 'Picking' auf meiner Erklärung. Ich habe einige "Abkürzungen" in meiner Erklärung verwendet, um zu vermeiden, dass komplexe Konzepte (wie Zeigerzuweisung) die Dinge sehr einfach halten. @gath hat eine grundlegende Frage gestellt, was bedeutet, dass er immer noch die Grundlagen der Programmierung lernt.
Vorsicht. Da stack-allocated Variablen nicht auf 0 initialisiert werden, und assigned() nur auf <> nil prüft, wird die Assertion * nicht * ausgelöst, wenn sie vor dem Aufruf der Funktion nicht erzeugt wird. –
Guter Fang, Mason. Ich werde das in meinem Post korrigieren. –