Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Pointer of Dynamic Array (https://www.delphipraxis.net/184122-pointer-dynamic-array.html)

Crocotronic 27. Feb 2015 17:30

Pointer of Dynamic Array
 
Hallo zusammen,
bei der lkJSON-Klasse gibt es eine ForEach-Methode um eine Array eines JSON-Objekts auszulesen. Als Argument muss man die CallBack-Funktion angeben und irgendeine Datenstruktur (in meinem Fall ein dynamisches Array). Folgender Code:
Delphi-Quellcode:
type
  TElement = record
   Value: String;
  end;
  TElements = array of TElement;
  PElements = ^TElements;

procedure ExtractElements(AElementName: string; AElement: TlkJSONbase; ADataPtr: Pointer; var Continue: Boolean);
var Elements: PElements;
begin
 Elements:= PElements(ADataPtr);

 SetLength(Elements^,High(Elements^)+2);
 Elements^[High(Elements^)].Value:= xxxx;
 showmessage(inttostr(High(Elements^)));
end;

// Aufruf:
var MyElements: TElements;
(AJSON.Field['su'] as TlkJSONlist).ForEach(ExtractElements, @MyElements);
Jetzt ist mein Problem, dass die Länge von dem Array nicht wächst, sonder imm bei 1 bleibt. Also das
Delphi-Quellcode:
showmessage
gibt mir immer 0 zurück (was dann Count=1 bedeutet).
Warum?

Viele Grüße
Croco

Bjoerk 27. Feb 2015 18:20

AW: Pointer of Dynamic Array
 
Hast du mal testhabler eine Stringlist übergeben?
Delphi-Quellcode:
procedure ExtractElements(AElementName: string; AElement: TlkJSONbase;
  ElementList: TStringList; var Continue: Boolean);
begin
  ElementList.Add(..);
end;

(AJSON.Field['su'] as TlkJSONlist).ForEach(@ExtractElements, MyElementList);

himitsu 27. Feb 2015 18:26

AW: Pointer of Dynamic Array
 
"theoretisch" sieht es so aus, als wenn es richtig wäre.

@StringList: Dort bleibt der Zeiger immer gleich und nur in dem Objekt ändert sich die Liste.
Beim Array wird der Speicher immer mal wieder verschoben, weswegen sich dort der Zeiger ändert, auf den sein Pointer zeigt, aber durch den Pointer sollte man ja immer richtig direkt auf die Variable zugreifen. :gruebel:


Rein logisch meinst du doch bestimmt
Delphi-Quellcode:
SetLength(Elements^, Length(Elements^)+1);
oder
Delphi-Quellcode:
SetLength(Elements^, Succ(Length(Elements^)));
aka "um 1 vergrößern" ?

Crocotronic 27. Feb 2015 18:54

AW: Pointer of Dynamic Array
 
Delphi-Quellcode:
SetLength(Elements^, Length(Elements^)+1);
Stimmt, so geht's einfacher.
Aber das Problem bleibt. Direkt nach dem Aufruf von
Delphi-Quellcode:
ForEach
ist die Länge von MyElements = 0, obwohl ich sie ja definitiv erhöhe :|
An der ForEach-Methode kann es nicht liegen, da
Delphi-Quellcode:
procedure IncDynRec(ADataPtr: Pointer);
var Elements: TElements;
begin
 Elements:= PElements(ADataPtr)^;
 SetLength(Elements,Length(Elements)+1);
end;
genau so nicht funktioniert

MStoll 27. Feb 2015 22:23

AW: Pointer of Dynamic Array
 
Zunächst mal solltest du Code posten, der zumindest syntaktisch so funktionieren würde.

Zu Beginn z.B. schreibst du
Delphi-Quellcode:
PElements = ^Elements
, wo ein "T" nach dem "^" fehlt oder später
Delphi-Quellcode:
Elements^[High(Elements)].Value:= xxxx
, wo das "^" im Aufruf von high(..) fehlt. Und beim letzten Post stellt sich die Frage, was "Subjects" ist? Elements wird da beispielsweise gar nicht instantiiert...

Fehler in Code zu suchen, der vor dem Posten erst noch umgeschrieben wird, könnte vielleicht sinnlos sein, da der eigentliche Fehler durch das Umschreiben möglicherweise verschleiert wird.

Crocotronic 27. Feb 2015 23:05

AW: Pointer of Dynamic Array
 
Stimmt, da sind mir wohl einige Fehler unterlaufen.
Ich versuche als meinen Code zu abstrahieren und exemplarisch anschaulich zu gestalten und ändere ihn deshalb direkt hier im Editor,
deshalb fallen mir solche Fehler nicht auf. Ich werde in Zukunft darauf achten, dass ich den Code kompiliere und fehlerfrei hier poste.
Vielen Dank für den Hinweis.

Was die Thematik betrifft: ich habe jetzt halt eine Klasse draus gemacht und speicher alle Objekte in einer TObjectList.
Somit wäre das Problem für mich nun gelöst, dennoch würde mich interessieren warum der Code nicht funktioniert. Vielleicht ergibt sich ja noch etwas.

Bjoerk 28. Feb 2015 01:36

AW: Pointer of Dynamic Array
 
TObjectlist? Bist du sicher, daß du #2 verstanden hast?

himitsu 28. Feb 2015 08:59

AW: Pointer of Dynamic Array
 
Joar, wie man schon an der #2 sieht, kann man hier beliebig die Prozedur-Signatur (Parameter) ändern, da man nur einen untypisierten Pointer zur Callback-Prozedur rein gibt.

Delphi-Quellcode:
procedure ExtractElements(AElementName: string; AElement: TlkJSONbase; ADataPtr: PElements; var Continue: Boolean);
begin
 SetLength(ADataPtr^, Length(ADataPtr^)+1);
 ADataPtr^[High(ADataPtr^)].Value:= xxxx;
 ShowMessage(IntToStr(Length(ADataPtr^)));
end;

procedure ExtractElements(AElementName: string; AElement: TlkJSONbase; var AData: TElements; var Continue: Boolean);
begin
 SetLength(AData, Length(AData)+1);
 AData[High(AData)].Value:= xxxx;
 ShowMessage(IntToStr(Length(AData)));
end;

// Aufruf(e):
var MyElements: TElements;
(AJSON.Field['su'] as TlkJSONlist).ForEach(ExtractElements, @MyElements);


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:44 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