AGB  ·  Datenschutz  ·  Impressum  







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

Risiko dyn.array als Funktionsrückgabewert ???

Ein Thema von bernhard_LA · begonnen am 8. Mär 2012 · letzter Beitrag vom 9. Mär 2012
Antwort Antwort
Seite 1 von 2  1 2      
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.138 Beiträge
 
Delphi 11 Alexandria
 
#1

Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 15:25
wir haben einen Datentyp


    TINTEGERList2D = array of array of Integer
Im Program gibt es jede Menge an Funktionen wie
Delphi-Quellcode:
 
    ...;
    function Make_Something (var aList :TINTEGERList2D ) : Real;
    function Make_SomethingOther (x,y : Integer) : TINTEGERList2D;
     ...;

Wir hatten das Programm schon im Einsatz, lief ganz gut. Nach den letzten Änderungen bekommen wir eine AV
Delphi versucht eines unserer Felder/Listen 2 x freizugeben (lt. FASTMM4) . Nur sehen wir leider nicht die Position im Code ....
und warum sehe ich erst recht nicht


Sind Zuweisungen wir

Delphi-Quellcode:
aList : :TINTEGERList2D ;
           bList : :TINTEGERList2D ;


aList[i,j] := Blist [u,v];
ein mögliche Ursache ?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 15:47
aList[i,j] := Blist [u,v]; Ist ja im Endeffekt nur eine einfache Integerzuweisung und macht keine Probleme.
Ihr könnt aber dennoch mal, in den Projektoptionen, die Bereichsprüfung aktivieren, denn Schreibzugriffe auf nichtexistierende Fehler bereiten manchmal kleine Problemchen.

Aber aList := bList; oder aList[i] := bList[u]; sind da etwas anders zu betrachten, denn dyn. Arrays verfügen zwar über eine Referenzzählung, aber man hat "vergessen" diesen Arrays einen CopyOnWrite-Zugriff zu verpassen.

Wenn man bei Strings
Delphi-Quellcode:
var
  s, x: string;

s := '12345';
x := s; // erhöht nur die Referenzzählung
x[3] := 'a'; // führt vorher ein UniqueString auf x aus, bevor geschrieben wird.
ShowMessage(s + sLineBreak + x);
Delphi-Quellcode:
var
  s, x: array of Integer;

SetLength(s, 5);
s[0] := 1;
s[1] := 2;
s[2] := 3;
s[3] := 4;
s[4] := 5;
x := s; // erhöht auch nur die Referenzzählung
x[2] := 666; // schreibt einfach, ohne die Referenzzählung zu prüfen
ShowMessage(IntToStr(s[2]) + ' ' + IntToStr(x[2]));
Delphi-Quellcode:
...
s[4] := 5;
x := Copy(s); // kopiert das array, in eine eigenständige Instanz
x[2] := 666; // schreibt einfach, ohne die Referenzzählung zu prüfen
ShowMessage(IntToStr(s[2]) + ' ' + IntToStr(x[2]));
Delphi-Quellcode:
...
s[4] := 5;
x := s; // erhöht auch nur die Referenzzählung

x := Copy(x); // sicherstellen, daß x unique ist (zur Optimierung könnte man vorher noch die referenzzählung prüfen, ob überhaupt nötig)
x[2] := 666; // schreiben (die Referenzzälung wurde ja schon sichergestellt)
ShowMessage(IntToStr(s[2]) + ' ' + IntToStr(x[2]));

Aber so oder so, an der Referenzzählung sollte nichts kaputtgehn, abgesehn
- von Bufferoverruns
- wenn man die Array-Instanz-Referenzzählung direkt oder indirekt mit Pointern schrottet/umgeht
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 8. Mär 2012 um 15:50 Uhr)
  Mit Zitat antworten Zitat
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.138 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 16:29
Bereichsprüfung eingeschalten -> leider kein Erfolg



innerhalb der Funktionen sind die Setlenght Commands verbaut, alle dyn. Arrays werden als var Param übergeben, bzw. als Function result abgeholt ....
kann hier irgendwo ein Fehler liegen im Speichermanager ???
Wie finde ich den Fehler
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#4

AW: Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 16:31
Ich weiß nicht, ob das dein Problem ist, aber bei dynamischen Arrays als Rückgabewerten muss man beachten, dass sie eher als var-Parameter implementiert sind. Z.B. liefert folgendes Progrämmchen
Delphi-Quellcode:
program DynArrayReturn;

{$APPTYPE CONSOLE}

uses
  Types,
  SysUtils;

function MakeArrayRet(ASize: Integer): TIntegerDynArray;
begin
  Write(Length(Result): 3);
  SetLength(Result, ASize);
end;

procedure MakeArrayVar(var AArray: TIntegerDynArray; ASize: Integer);
begin
  Write(Length(AArray): 3);
  SetLength(AArray, ASize);
end;

procedure MakeArrayOut(out AArray: TIntegerDynArray; ASize: Integer);
begin
  Write(Length(AArray): 3);
  SetLength(AArray, ASize);
end;

procedure Test;
var
  a: TIntegerDynArray;
begin
  Write('Return:');
  a := nil;
  a := MakeArrayRet(10);
  a := MakeArrayRet(5);
  Writeln;

  Write('var: ');
  a := nil;
  MakeArrayVar(a, 10);
  MakeArrayVar(a, 5);
  Writeln;

  Write('out: ');
  a := nil;
  MakeArrayOut(a, 10);
  MakeArrayOut(a, 5);
  Writeln;
end;

begin
  try
    Test;
    Readln;
  except
    on E: Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
bei mir
Code:
Return: 0 10
var:    0 10
out:    0  0
DynArray-Rückgabewerte werden also nicht korrekt initialisiert!
Uli Gerhardt
  Mit Zitat antworten Zitat
Peter1999

Registriert seit: 13. Dez 2007
Ort: Dresden
88 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 17:11
Zitat:
DynArray-Rückgabewerte werden also nicht korrekt initialisiert!
Wieso? Was hättest du denn da anderes erwartet?

Für viel wahrscheinlicher halte ich, dass an irgendeiner Stelle der Array nicht sauber von 0..high() durchlaufen wird. Ist da versehentlich ein 1..length() dazwischen geraten? Wenn das passiert, treten die Zugriffsverletzungen leider nur selten sehr zeitnah auf und man sucht seeeehr lange.

Dass es an einer doppelten Freigabe des Speichermanagers liegt, halte ich eher für unwahrscheinlich. Wie kommst du denn zu der Erkenntnis?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 17:42
Zitat:
DynArray-Rückgabewerte werden also nicht korrekt initialisiert!
Wieso? Was hättest du denn da anderes erwartet?
Mit der Speicherverwaltung gibt es eigentlich keine Probleme.

Aber mit der Initialisierung muß man aufpassen.
http://www.delphipraxis.net/166950-s...ml#post1155075 (#16-#18)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#7

AW: Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 17:45
Zitat:
DynArray-Rückgabewerte werden also nicht korrekt initialisiert!
Wieso? Was hättest du denn da anderes erwartet?
Na halt, dass sie korrekt initialisiert werden.
Eine lokale verwaltete Variable (String, dyn. Array, Interface) wird ja auch null-initialisiert.

Für viel wahrscheinlicher halte ich, dass an irgendeiner Stelle der Array nicht sauber von 0..high() durchlaufen wird. Ist da versehentlich ein 1..length() dazwischen geraten? Wenn das passiert, treten die Zugriffsverletzungen leider nur selten sehr zeitnah auf und man sucht seeeehr lange.

Dass es an einer doppelten Freigabe des Speichermanagers liegt, halte ich eher für unwahrscheinlich. Wie kommst du denn zu der Erkenntnis?
Damit meinst du jetzt den OP, oder?
Uli Gerhardt
  Mit Zitat antworten Zitat
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#8

AW: Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 17:49
Zitat:
DynArray-Rückgabewerte werden also nicht korrekt initialisiert!
Wieso? Was hättest du denn da anderes erwartet?
Na halt, dass sie korrekt initialisiert werden.
Eine lokale verwaltete Variable (String, dyn. Array, Interface) wird ja auch null-initialisiert.

Sie sind korrekt initialisiert. Funktionsrückgabewerte sind eben keine lokalen Variablen.

Delphi-Quellcode:
function F(const X: Extended): Extended; begin Result := { ... }; end;
procedure F(const X: Extended; var Result: Extended); begin Result := { ... }; end;
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 18:00
Ordinale Typen, Fließkommatypen und alles mögliches kleines einfaches Getier, welches in ein Register paßt und wo kein schliommes Speichermanagement dahintersteht,
das sind "richtige" Rückgabewerte und keine impliziten Out/Var-Parameter.

Aber bei diesen Sachen, wie String und dyn. Array, ist das soeine Sache.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#10

AW: Risiko dyn.array als Funktionsrückgabewert ???

  Alt 8. Mär 2012, 18:19
Also ich würde dyn. Arrays nur innerhalb einer Klasse umherreichen.
Sobald das dyn. Array die Grenzen einer Klasse verlässt diese Technik nicht robust genug, um Daten sicher zu transportieren.

Ein dyn. Array ist wie DNS ohne eine schützende Zellwand drumrum; jeder kann (auch unabsichtliche) Änderungen vornehmen.
Wenn man das dyn. Array mit einer Klasse kapselt, kann man den Zugriff auf die inneren Daten genau kontrollieren.
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 00:09 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