Autor Beitrag
nike
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 48

Win 2K, Win XP
D5 Ent.
BeitragVerfasst: Mi 20.10.04 12:37 
Hallo!

Dyn. array ist schon viel besprochen, aber ich konnte leider nix zu meinem Problem finden. Verwende:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
  TPFeilStuetzPunktArray = array of TPoint;
  TPfeilRestriktionArray = array of TPfeilRestriktion; //Auch nur ein record

  TPfeil = record
    id   : integer;  //. usw.
    Stuetzpunkte : TPFeilStuetzPunktArray;
    Restriktionen : TPfeilRestriktionArray;
  end;
  
  TPfeilArray = array of TPfeil;


Das funktioniert zur Laufzeit wunderbar, bis auf das Entladen.
a) Wenn Stuetzpunkte keinen Eintrag enthaelt (Länge 0), dann kein Fehler
b) Wenn Stuetzpunkte Daten enthält, wird beim Entladen ein Speicherzugriffsfehler in der GetMem.inc, Funktion DeleteFree(f: PFree) erzeugt. ?!?
Pfeile werden freigegeben, gem. Delphi-Hilfe mit:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
  procedure FreeStrassen(var Strassen : TPfeilArray);
  var
    i : integer;
  begin
    for i := 0 to High(Strassen) do
    begin
      with Strassen[i] do
      begin
        SetLength(Stuetzpunkte, 0);
        Stuetzpunkte := nil;
        SetLength(Restriktionen, 0);
        Restriktionen := nil;
      end;
    end;
    SetLength(Strassen, 0);
    Strassen := nil;
  end;


Kann irgendwer helfen?

Noch was anderes. Habe beim Suchen oft die Meinung gefunden, daß ein dyn. array sehr ineffizient sein soll. Es wird oft die TList empfohlen. Dafür brauche ich doch aber ein Objekt/Zeiger, dass einzeln! erzeugt und freigegeben werden muß (Also auch zerstückelter Speicher). Dass ist doch sehr langsam. Record-Array ist wesentlich speicherschonender (wenn wenig SetLength aufgerufen wird und kopier-Operationen gemacht werden), Records am Block/Sück alloziert. Lasse mich da aber auch gerne belehren.

Gruß
nike
sourcehunter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 482

Win XP | Suse 10.1
Delphi 2005 Pers.
BeitragVerfasst: Do 21.10.04 12:20 
Warum weist du den dyn. Arrays noch nil zu? Meiner Meinung nach ist das unnötig, probiers mal ohne.

_________________
Linux und OpenSource rulez!
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Do 21.10.04 12:44 
Ich denke auch, dass da das Problem liegt. Ob was im Array steht kann man ja auch mit Length(arr) prüfen.
opfer.der.genauigkeit
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: Do 21.10.04 13:33 
Teste das hier mal und schau dir das im Debugger an.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.FormCreate(Sender: TObject);
var
  ary: array of string;
begin
  SetLength(ary, 1);
  ary[0] := 'test';
  SetLength(ary, 0); // ab hier ist ary = nil, wenn du pointer(ary) prüfst
end;


Es gibt also keinen Eintrag mehr.
Aber eine Zuweisung auf ary := nil gibt keinen Fehler.

Aber ich laße mich auch gerne belehren.
:wink:

Was mich aber zu einer Interessanten Frage bring:
Wo liegt der exakte Unterschied zwischen pointer(ary) und @ary?
Gibt @ die absolute Adresse an und pointer() sucht sich den Wert an dieser Stelle? *verwirrt ist*

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.

_________________
Stellen Sie sich bitte Zirkusmusik vor.
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Do 21.10.04 13:41 
Ist zwar schon ein bisschen her, aber ich hatte damals(anno 1890 :wink: ) ein Problem mit Assigned und dynamischen Arrays.

Das mit Pointern und @ und vari^ habe ich mich zwar auch schonmal gefragt, aber nie die Muße, das mal genau zu überprüfen.

Wers weiß, kann uns ja mal schlau machen.
opfer.der.genauigkeit
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: Do 21.10.04 13:41 
nike hat folgendes geschrieben:


b) Wenn Stuetzpunkte Daten enthält, wird beim Entladen ein Speicherzugriffsfehler in der GetMem.inc, Funktion DeleteFree(f: PFree) erzeugt. ?!?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
  procedure FreeStrassen(var Strassen : TPfeilArray);
  var
    i : integer;
  begin
    for i := 0 to High(Strassen) do
    begin
      with Strassen[i] do
      begin
        SetLength(Stuetzpunkte, 0);
        Stuetzpunkte := nil;
        SetLength(Restriktionen, 0);
        Restriktionen := nil;
      end;
    end;
    SetLength(Strassen, 0);
    Strassen := nil;
  end;




b) Objekte mußt du die Elemente im Array explizit freigeben. (Bei Records mußt das nicht machen)

für High würde ich Length benutzen.

_________________
Stellen Sie sich bitte Zirkusmusik vor.
nike Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 48

Win 2K, Win XP
D5 Ent.
BeitragVerfasst: Do 21.10.04 17:43 
Hallo!

Da hat sich ja einiges getan... :D

Taj, erst hatte ich die händische Freigabe nicht, wie opfer.der.genauigkeit beschrieben,
Delphi großzügig überlassen.

Dann traten die Probleme auf.

Deshalb habe ich mit der händischen Freigabe eigentlich alles mit SetLength=0 nis nur nil, etc. durchprobiert. nil zuweisen oder nicht ist von der Fehlermeldung her gleich.

Glaube, daß Problem liegt eher an der Verschachtelung des Open Record-Array innerhalb eines andren Records die wiederum in OpenArrays liegen.

Der Speicherzugriffsfehler kommt ja in der GetMem.inc, Funktion DeleteFree(f: PFree), wobei ich nicht weiß was die GetMem.Inc macht, wofür zuständig, etc. (Glaube aber halt irgendwelche kryptischen Speicherverwaltungsgeschichten).

Habe jetzt die OpenArrays aus den Records in seperate, parallele Arrays gepackt, also ohne Verschachtelung. Das gefällt mir aber nicht, da ich jetzt 3x SetLength(PfeilAnzahl) in meiner übergeordneten Klasse für die ursprünglichen Pfeile und jetzt noch Stützpunkte und Restriktionen aufrufen muß. Sehr leicht fehleranfällig.

Also, wenn jemand noch weitere Speicherfehlermöglichkeiten kennt?!?

Zu:
Zitat:

Ist zwar schon ein bisschen her, aber ich hatte damals(anno 1890 ) ein Problem mit Assigned und dynamischen Arrays.

Das mit Pointern und @ und vari^ habe ich mich zwar auch schonmal gefragt, aber nie die Muße, das mal genau zu überprüfen.

Wers weiß, kann uns ja mal schlau machen.


Informationen (Datentypen) sind nur Speicherinterpretationen an der Speicherstelle, die mit dem @-Operator abgefragt wird. Dem Datentyp Pointer, ein Verweis auf eine Speicherstelle (Adresse), ist die Interpretation egal (ob ein byte, oder ein char). Der Pointer ist eine Variable, der explizit eine Adresse zugewiesen werden kan, wie mit @ abgefragt.

Alle anderen Datentypen sind auch Pointer im Prinzip, die aber schon von der Länge und der Interpretation, damit verbunden die mögliche Operationen, her festgelegt sind.

Delphis Hilfe selbst meint:

Zitat:

Mit der folgenden Syntax kann ein Zeiger auf jeden beliebigen Typ deklariert werden:

type Zeigertypname = ^Typ

Es ist gängige Programmierpraxis, bei der Definition eines Record-Typs oder eines anderen Datentyps auch einen Zeiger auf diesen Typ zu deklarieren. Dies erleichtert die Verarbeitung von Instanzen des Typs, da das Kopieren größerer Speicherblöcke entfällt.
Es gibt Standardzeigertypen für unterschiedliche Verwendungszwecke. Mit dem Allzwecktyp Pointer kann jeder Datentyp referenziert werden. Eine Dereferenzierung von Variablen des Typs Pointer ist nicht möglich. Den Versuch, einer Pointer-Variablen das Symbol ^ nachzustellen, weist der Compiler zurück. Wenn Sie auf Daten zugreifen wollen, auf die eine Pointer-Variable zeigt, müssen Sie diese Variable in einen anderen Zeigertyp umwandeln, bevor Sie sie dereferenzieren.



Naja, früher war das unter DOS ganz witzig den ausgelagerten Videospeicher zu manipulieren, da hat man direkt auf den Speicher zugegriffen (an B$800 oder so) und die Texte, Textfarbe und Hintergrundfarbe verändert, aber Windows nimmt einen sowas ja übel...

Gruß
nike