AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

A/V bei löschen von Element in Array

Ein Thema von WorstNightmare · begonnen am 16. Jul 2010 · letzter Beitrag vom 17. Jul 2010
Antwort Antwort
WorstNightmare

Registriert seit: 6. Okt 2008
159 Beiträge
 
RAD-Studio 2010 Arc
 
#1

A/V bei löschen von Element in Array

  Alt 16. Jul 2010, 23:59
Delphi-Version: 2010
Hallo,

ich habe eine eigene StringListen Klasse für Plugin-DLLs geschrieben, damit ich Classes nicht einbinden muss (und sie somit nicht so aufgebläht werden). Die Liste bietet außerdem einige Extra-Funktionen, z.B. einen Filter darauf anzuwenden, d.h. alle Elemente die Filter nicht enthalten werden gelöscht.

Delphi-Quellcode:
procedure TCSList.ApplyFilter(F: string);
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
    if Pos(F, FArray[i]) = 0 then
      if i = Count - 1 then
        SetLength(FArray, Count - 1)
      else
      begin
        Move(FArray[i + 1], FArray[i], (Count - 1 - i) * 4); // String = 4 Byte Pointer
        SetLength(FArray, Count - 1);
        ApplyFilter(F); // Count geändert, Schleife neustarten
        Exit;
      end;
end;
Das ganze basiert auf einem array of string (FArray), Count gibt einfach nur Length(FArray) aus. Das Problem ist, dass nach einem Durchlauf der Speicher irgendwie korrumpiert wird, denn plötzlich tauchen im Array noch andere Strings die irgendwo in der DLL vorkommen auf und irgendwann ist es dann so kaputt, dass eine A/V geworfen wird.

Vielleicht mögen die String-Pointer es nicht rumgeschoben zu werden? Ich konnte den Fehler nicht finden
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: A/V bei löschen von Element in Array

  Alt 17. Jul 2010, 01:11
Wenn du die Stringreferenzen nicht korrekt behandelt, dann muß es ja probleme geben.

der String, welchen du "angelich" löschts ... da überschreibst du nur den "Zeiger", aber der String selber bleibt als Speicherleck zurück.

Und als Ausgleich hast du durch dein Move auch noch den letzen String im Array mit einer doppelten Referenz, welcher aber nicht in der Referenzzählung auftaucht, womit der dann schon freigegeben wird, aber dennoch in der Liste steht ... taj, beim nächsten Zugriff darauf, da muß es einfach knallen.


Mein Tipp: verwende eine echte Stringliste, statt des Arrays ... so sehr aufblähen tut soeine Liste auch nicht und du mußt nicht an der Referenzzählung rumfummeln.

Ansonten mußt du die Zeiger halt korrekt behandeln, also manuell auf nil, bzw. einen Leerstring setzen.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von rollstuhlfahrer
rollstuhlfahrer

Registriert seit: 1. Aug 2007
Ort: Ludwigshafen am Rhein
1.529 Beiträge
 
Delphi 7 Professional
 
#3

AW: A/V bei löschen von Element in Array

  Alt 17. Jul 2010, 10:57
Move(FArray[i + 1], FArray[i], (Count - 1 - i) * 4); // String = 4 Byte Pointer
Das kannst du SO nicht machen. Strings selbst sind ja Arrays. Und wenn du jetzt anfängst in deinem FArray rumzuschieben, bringst du die ganze Struktur durcheinander. Einfacher ist es einfach zu sagen FArray[i] := FArray[i + 1] . Dies hat den Vorteil, dass der Compiler auch weiß, was du machen willst und sich demnach richten kann.

Bernhard
Bernhard
Iliacos intra muros peccatur et extra!
  Mit Zitat antworten Zitat
WorstNightmare

Registriert seit: 6. Okt 2008
159 Beiträge
 
RAD-Studio 2010 Arc
 
#4

AW: A/V bei löschen von Element in Array

  Alt 17. Jul 2010, 11:02
So, habe jetzt vor dem Move
FArray[i] := ''; // Zu löschenden freigeben das hinzugefügt.
Jetzt läuft der Code ohne Probleme durch, aber wie kann ich die doppelte Referenz verhindern? Der letzte Pointer steht dann ja kurzfristig 2x in der Liste (bis SetLength die Liste verkleinert), aber wenn ich den hinteren auf leer setze betrifft das ja auch den vorletzten.

@rollstuhlfahrer:
Strings sind Zeiger auf Arrays, das "Array" selbst steht woanders.
  Mit Zitat antworten Zitat
Benutzerbild von rollstuhlfahrer
rollstuhlfahrer

Registriert seit: 1. Aug 2007
Ort: Ludwigshafen am Rhein
1.529 Beiträge
 
Delphi 7 Professional
 
#5

AW: A/V bei löschen von Element in Array

  Alt 17. Jul 2010, 11:11
Hab ich mir auch noch nie Gedanken gemacht. Ich hätte gleich die Delete()-Funktion der Stringliste aufgerufen. So hätte ich mit Denkaufwand und Redundanz gespart.

Bernhard
Bernhard
Iliacos intra muros peccatur et extra!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: A/V bei löschen von Element in Array

  Alt 17. Jul 2010, 12:05
Delphi-Quellcode:
FArray[i] := '';
Move(FArray[i + 1], FArray[i], (Count - 1 - i) * SizeOf(Pointer));
Pointer(FArray[Count - 1]) := nil;
SetLength(FArray, Count - 1);
Aber, wie gesagt, nimm lieber eine Stringliste .. diese ist nur unwesentlich größer, der Overhead ist minimal und man erspart sich viel Arbeit und eventuelle Probleme und nur ein Delete(i) wäre auch verständlicher.

Und vorallem, wenn man nciht genau weiß was man macht und warum, ist es eh keine gute Idee Automatismen (wie die delphiinterne Speicherverwaltung/Referenzzählung) zu manipulieren.
$2B or not $2B

Geändert von himitsu (17. Jul 2010 um 12:09 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:58 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz