AGB  ·  Datenschutz  ·  Impressum  







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

Pointer wirrwarr. Bitte um hilfe

Ein Thema von hedie · begonnen am 4. Feb 2016 · letzter Beitrag vom 5. Feb 2016
Antwort Antwort
Seite 1 von 2  1 2      
hedie

Registriert seit: 12. Dez 2005
Ort: Schweiz
1.024 Beiträge
 
Delphi XE6 Starter
 
#1

Pointer wirrwarr. Bitte um hilfe

  Alt 4. Feb 2016, 22:32
Hallo zusammen

Dieser Code war meine Grundlage:
Delphi-Quellcode:
type
  TTreeData = record
    FCaption: string;
    FColumn1: string;
  end;
  PTreeData = ^TTreeData;
...
procedure TForm1.Button2Click(Sender: TObject);
var
  Node : PVirtualNode;
  Data:PTreeData;
begin

  //Data ist nur ein Pointer auf eine Datenstruktur von TTreeData;
  vst.BeginUpdate;

  //Zuerst holen wir uns den Node
  Node := VST.AddChild(nil);

  //VST kennt bereits die grösse der Struktur und hat hier genau soviel Speicher bereit gestellt
  //Wir übergeben Data nun die Adresse des Speichers von VST.
  Data := vst.GetNodeData(node);

  //Nun können wir direkt in den Node Speicher hinein schreiben.
  Data^.FCaption := 'Test';
  Data^.FColumn1 := 'Column';

  vst.EndUpdate;

end;
Wie man erkennen kann, handelt es sich um VirtualTreeView.


Ich habe nun versucht anstelle des Records ein dynamisches array bestehend aus strings zu benutzen.
Dazu habe ich folgendes versucht:


Delphi-Quellcode:
type
  TsqlData = array of string;
  PsqlData = ^TsqlData;

...


function TeVCLqueryTable.Query(Query: string):integer;
var
  row,col:integer;
  node:PVirtualNode;
  sqlData:PsqlData;
begin
  FMySQL.Query(Query);

  //SQLColCount ist 11
  for col := 0 to FMySQL.SQLColCount - 1 do begin
    FVST.Header.Columns.Add;
  end;

  FVST.BeginUpdate;
 
  SetLength(sqlData^,FMySQL.SQLColCount); //SQLColCount ist 11
  FVST.NodeDataSize := sizeof(sqlData);

  node := FVST.AddChild(nil);
  sqlData := FVST.GetNodeData(node);

  sqlData^[0] := 'Test'; //<-- Hier kommt eine exception

  Result := FMySQL.SQLRowCount;

  FVST.EndUpdate;
end;


Ich wäre froh, wenn mir hier jemand weiterhelfen könnte.

Es geht um das Problem mit den Pointern.
Irgendwas mache ich falsch ^^

Danke
Claudio
Tu was du nicht lassen kannst
- http://endasmedia.ch
  Mit Zitat antworten Zitat
EmWieMichael

Registriert seit: 28. Mär 2012
103 Beiträge
 
#2

AW: Pointer wirrwarr. Bitte um hilfe

  Alt 5. Feb 2016, 08:05
Deine Pointer zeigen ins Nirwana. Sieh Dir mal 'New' und 'Dispose' an...

Gruß Michael
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.380 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Pointer wirrwarr. Bitte um hilfe

  Alt 5. Feb 2016, 08:20
Ich habe nun versucht anstelle des Records ein dynamisches array bestehend aus strings zu benutzen.
Dazu habe ich folgendes versucht:
.....
Es geht um das Problem mit den Pointern.
Irgendwas mache ich falsch ^^
ich habe zwar schon lange nicht mehr mit dynamischen Arrays gearbeitet, aber wenn ich das noch richtig im Kopf habe, sollte man da über SetLength und co. doch entsprechenden Speicher reservieren? Sprich nach deinem GetNodeData() solltest Du schauen wie groß das Array ist und dann über SetLength ggf. weitere ELemente dazu fügen.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Pointer wirrwarr. Bitte um hilfe

  Alt 5. Feb 2016, 08:42
ich habe zwar schon lange nicht mehr mit dynamischen Arrays gearbeitet, aber wenn ich das noch richtig im Kopf habe, sollte man da über SetLength und co. doch entsprechenden Speicher reservieren? Sprich nach deinem GetNodeData() solltest Du schauen wie groß das Array ist und dann über SetLength ggf. weitere ELemente dazu fügen.
Er hat ein Pointer auf ein dynamisches Array, deswegen muss er wie EmWieMichael gesagt hat mit New das Array erzeugen und danach erst mit SetLength die größe des Arrays setzen.
(Später dann wie gesagt mit Dispose die Arrays frei geben!)
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#5

AW: Pointer wirrwarr. Bitte um hilfe

  Alt 5. Feb 2016, 11:58
Oder man macht es wie im oberen Beispiel mit den Strings und packt einen Record um das Array. Dann muss man aber auch im OnFreeNode das Array wieder auf nil setzen.

Delphi-Quellcode:
type
  TsqlData = record
    Data: array of string;
  end;
  PsqlData = ^TsqlData;

procedure ...GetNodeDataSize(Sender: TBaseVirtualTree;
  var NodeDataSize: Integer);
begin
  { Alle Nodes haben dieselbe DataSize! Aber nicht alle Nodes müssen zwingend dieselbe Array-Länge haben. }
  NodeDataSize := SizeOf(TsqlData);
end;

procedure ...FreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
  sqlData:PsqlData;
begin
  sqlData := Sender.GetNodeData(node);
  sqlData.Data := nil;
end;

function Query(Query: string):integer;
var
  row,col:integer;
  node:PVirtualNode;
  sqlData:PsqlData;
begin
  FMySQL.Query(Query);

  //SQLColCount ist 11
  for col := 0 to FMySQL.SQLColCount - 1 do begin
    FVST.Header.Columns.Add;
  end;

  FVST.BeginUpdate;
  try
    node := FVST.AddChild(nil);
    sqlData := FVST.GetNodeData(node);
    SetLength(sqlData.Data,FMySQL.SQLColCount); //SQLColCount ist 11
    sqlData[0] := 'Test';
  finally
    FVST.EndUpdate;
  end;

  Result := FMySQL.SQLRowCount;
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.380 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Pointer wirrwarr. Bitte um hilfe

  Alt 5. Feb 2016, 12:19
Er hat ein Pointer auf ein dynamisches Array....
hmm... Ich gebe ja gerne zu, dass ich mit Pointern schon immer so meine Probleme habe. Aber was gibt denn .GetNodeData bitte schön zurück, wenn nicht einen pointer auf einen Speicherbereich in das das array gehört? Den Bereich definiere ich mit NodeDataSize und der VST kümmert sich drum, dass dort ein Pointer mit der Größe angelegt wird. Wie ich den interpretiere ist dann meine Sache - auch wenn ich innerhalb dieses Pointers auf weitere Speicherbereiche zugreife die ich dann zu verwalten habe....

Das hier funktioniert bei mir problemlos:

Delphi-Quellcode:

procedure TForm1.FormCreate(Sender: TObject);
begin
  FVST.NodeDataSize := sizeof(PsqlData);
end;

procedure TForm1.Button1Click(Sender: TObject);
var sqlData:PsqlData;
   node:PVirtualNode;
begin
  node := FVST.AddChild(nil);
  sqlData := FVST.GetNodeData(node);
  SetLength(sqlData^, 2);
  sqlData^[0]:='Hallo';
  sqlData^[1]:='Welt';
end;

procedure TForm1.FVSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var sqlData:PsqlData;
idx: Integer;
begin
  sqlData := FVST.GetNodeData(Node);
  CellText := '';
  if Assigned(sqlData) then
  begin
    for idx := 0 to length(sqlData^) - 1 do
    begin
      CellText := CellText + sqlData^[idx];
    end;
  end;

end;
Es fehlt noch die Freigabe der dynamischen Arrays bei beenden.
Ich wüsste auch nicht wo genau jetzt der Unterschied zwischen einem dynamischen Array und dem Record von Uwes Beispielcode sein soll. Es sind am Ende Variablen. Ich wäre echt dankbar, wenn mir jemand das erklären kann...
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#7

AW: Pointer wirrwarr. Bitte um hilfe

  Alt 5. Feb 2016, 13:39
Ich wüsste auch nicht wo genau jetzt der Unterschied zwischen einem dynamischen Array und dem Record von Uwes Beispielcode sein soll. Es sind am Ende Variablen. Ich wäre echt dankbar, wenn mir jemand das erklären kann...
Der Unterschied ist rein semantisch. Die Speicherstruktur und der erzeugte Code sind wohl so gut wie identisch. Der Record-Ansatz erfordert halt keine Pointer-Dereferenzierung und ist später leichter zu erweitern, aber das muss hier ja nicht unbedingt ein Kriterium sein.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
hedie

Registriert seit: 12. Dez 2005
Ort: Schweiz
1.024 Beiträge
 
Delphi XE6 Starter
 
#8

AW: Pointer wirrwarr. Bitte um hilfe

  Alt 5. Feb 2016, 18:07
Vielen Dank für eure Hilfe.
Dies habe ich nun verstanden und es hat auch geklappt!

Nu habe ich gleich noch eine andere Frage zum selben Thema.

Ich habe bei mir in der hauptunit ein ObjektA erstellt, welches ich im private bereich deklariert habe.
Dieses erstelle ich beim öffnen der Anwendung.

Während der Laufzeit, möchte ich mit diesem ObjektA arbeiten.
Um mit diesem ObjektA arbeiten zu können, habe ich mir eine zweite Klasse geschrieben, welche die entsprechenden "bearbeitungs methoden" beinhaltet. Damit ich mit dieser Klasse arbeiten kann, muss ich davon ja auch ein ObjektB erstellen. Soweit so gut. Klappt auch.

Nun möchte ich bei einem Button click, das ObjektB, welches mir Hilft ObjektA zu bearbeiten, erstellen -> verwenden -> und wieder freigeben.

Hier gibts das Problem. Da ich bisher nicht ans freigeben gedacht habe, hab ich das erst jetzt bemerkt.

Ich übergebe ObjektB folgendes beim Create:

Delphi-Quellcode:
FVST:TVirtualStringTree;
FMySQL:TmySQLe;

constructor TeVCLqueryTable.Create(const VST: TVirtualStringTree; const MySQL:TmySQLe);
begin
  FVST := VST;
  FMySQL := MySQL;
...
Beim ObjectB.Free bekomme ich eine Exception.
Ich vermute mal, dass es dabei auch die übergebenen Objekte VST und MySQL freigegeben hat.
Dann wäre mir klar, dass es nicht mehr funktioniert!

Eigentlich möchte ich nur einen Pointer auf das ObjektA bzw. VST und MySQL damit ich mit diesen bereits existierenden Objekten innerhalb meines neuen Objektes arbeiten kann.

Nach dem Freigeben von ObjektB sollen die Objekte VST und MySQL weiterleben.


Könnte mir hier jemand weiterhelfen?

Vielen Dank
Claudio
Tu was du nicht lassen kannst
- http://endasmedia.ch
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Pointer wirrwarr. Bitte um hilfe

  Alt 5. Feb 2016, 18:10
Hallo,
wie sieht denn der Destructor der Klasse TeVCLqueryTable (also von ObjectB) aus, den Constructor sehe ich ja.


Heiko
Heiko

Geändert von hoika ( 5. Feb 2016 um 18:12 Uhr)
  Mit Zitat antworten Zitat
hedie

Registriert seit: 12. Dez 2005
Ort: Schweiz
1.024 Beiträge
 
Delphi XE6 Starter
 
#10

AW: Pointer wirrwarr. Bitte um hilfe

  Alt 5. Feb 2016, 18:12
Bisher sieht der so aus:

Delphi-Quellcode:
destructor TeVCLqueryTable.Destroy;
begin

  //FVST := nil;
  //FMySQL := nil;

  inherited;
end;
Wie du an den kommentaren siehst, war ich mir nicht ganz sicher... ^^
Claudio
Tu was du nicht lassen kannst
- http://endasmedia.ch
  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 05:42 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