Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.153 Beiträge
 
Delphi 12 Athens
 
#6

AW: Access Violation durch Length(Array)?

  Alt 28. Nov 2012, 16:30
Direkt einen Fehler seh ich in deinen Funktionen eigentlich nicht.
Deine Schleife ist soweit sicher, aber im Notfalls darfst du gerne die Bereichsprüfung in den Projektoptionen aktivieren, welche dann die indize der Array-Zugriffe prüft, ob da nichts außerhalb des Speicherbereichs liegt.
(hätte ja sein können, daß du stattdessen einfach alles zusammen per Move verschiebst und nicht jeden Eintrag einzeln)

Das was dein Array zerschießt kann aber auch eine komplett andere Codezeile sein ... fremden Speicher darf man auch kaputtmachen und nicht nud den Eigenen.
Es kann natürlich auch sein, daß die TTapiLine-Instanz weg ist oder daß dur irgendwo nicht threadsave auf diese Funktionen zugreifst.


Delphi-Quellcode:
procedure TTapiLine.AddCall(Call: TTapiCall);
begin
  //Call schon im Array drin ist, dann hat dein Remove problemchen, weil es ja nur nach einem Eintrag sucht und nicht nach mehreren
  SetLength(priv_Calls, Length(priv_Calls)+1); // mit Length ist's hier "verständlicher", was gemacht wird
  priv_Calls[High(priv_Calls)]:=Call;
end;

procedure TTapiLine.AddCall(CallHandle: Cardinal);
var Call:TTapiCall;
begin
  // nur wenn Initialized keine Exceptions erzeugen kann, dann wird .Free sicher aufgerufen (Fehler im AddCall einfach mal ausgeschlossen)
  Call:=TTapiCall.Create(CallHandle);
  if Call.Initialized then
    AddCall(Call)
  else
    Call.Free;
end;

procedure TTapiLine.RemoveCall(CallHandle: Cardinal);
var i,j:integer;
begin
  // durch die umgedrehte und leicht veränderte While-Prüfung, konnte das erste IF entfallen und das Zweite vereinfacht werden,
  // da im While nur vorhandene und davon alle Einträge geprüft werden
  i := Low(priv_calls);
  while (i < Length(priv_calls)) and (priv_calls[i].Handle <> CallHandle) do // oder (i <= High(priv_calls))
    inc(i);
  if i < Length(priv_calls) then
    begin
      for j := i+1 to High(priv_Calls) do
        priv_Calls[j-1] := priv_Calls[j]; // sprechender Code ... -1 = 1 vorkopieren (OK, das alte +1 = von dahinter herholen geht notfalls och)
      Setlength(priv_Calls, Length(priv_Calls)-1); // wie oben
    end;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (28. Nov 2012 um 16:32 Uhr)
  Mit Zitat antworten Zitat