Einzelnen Beitrag anzeigen

blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#1

Objekt in Array kopieren und anschließend freigeben

  Alt 30. Aug 2008, 20:45
Hallo.

Ich habe in einem Projekt Records in Klassen umgewandelt, da ich von diesen nun ableiten kann. Seit dem erhalte ich eine AV.

Hier erstmal der vereinfachte Code zur Reproduktion:

Delphi-Quellcode:
type
  // Anmerkung: War mal ein record, andere Klassen leiten aber jetzt hiervon ab
  TSubmission = class
    Tags: string;
    Rating: string;
    Score: integer;
    PictureNumber: integer;
    MD5: string;
  end;

  TSubmissionArray = array of TSubmission;

procedure AddToArray(var SubmissionArray: TSubmissionArray; const Value: TSubmission);
var
  l: integer;
begin
  l := Length(SubmissionArray);
  SetLength(SubmissionArray, l + 1);
  SubmissionArray[l] := Value;
end;

function Collect: TSubmissionArray;
var
  i: integer;
  Submission: TSubmission;
  tmp: TSubmissionArray;
begin
  for i := 0 to 10 do
  begin
    Submission := TSubmission.Create;
    try
      Submission.MD5 := 'test'+IntToStr(i);

      AddToArray(tmp, Submission);
    finally
      Submission.Free; // PROBLEM!
    end;
  end;

  showmessage(tmp[2].MD5); // Leer, durch Free()

  result := tmp;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x: TSubmissionArray;
begin
  x := Collect;

  showmessage(x[2].MD5); // Leer, durch Free();
  // In einem anderen Projekt sogar eine AccessViolation bei ntdll.dll
end;
Submission ist ein Objekt vom Typ TSubmission und wird 10 Mal dynamisch erstellt und mit Werten belegt. Anschließend möchte ich die Submission in einen SubmissionArray hängen (siehe AddToArray).

Anschließend gebe ich Submission frei. Und dies verursacht bei mir eine AV bei allen zukünftigen Zugriffen auf die Array-Elemente und deren Eigenschaften.

Kommentiere ich die Zeile "Submission.Free" aus, funktioniert alles. Dies erachte ich jedoch als ein Problem, da der Speicher nicht freigegeben wird.

Was passiert hier? Wieso wird in der Funktion AddToArray() keine Kopie der TSubmission-Instanz gemacht, die in den Array wandert? Wieso gehen die Array-Elemente kaputt, wenn ich das Originalstück freigebe?

Bei Strings, die als Variable in eine Funktion wandern, kenne ich die Routine UniqueString(). Hier muss ich mein TSubmission irgendwie auch "einzigartig" machen, oder?

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat