AGB  ·  Datenschutz  ·  Impressum  







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

Array als Pointer übergeben

Ein Thema von Captnemo · begonnen am 28. Okt 2015 · letzter Beitrag vom 29. Okt 2015
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#1

Array als Pointer übergeben

  Alt 28. Okt 2015, 12:54
Hi,

ich will mal was versuchen. Weniger, weil es Sinn macht, sondern nur zu meinem Verständnis. Versucht habe ich das schon, ab hinbekommen habe ich es nicht.

Ich möchte gerne mal ein Array in eine Pointer wandeln und hinterher wieder zurück.

In der ersten Unit:
Delphi-Quellcode:
uses Unit2;

interface

Type
  TMyArray: Array [0..9] of Integer;
.
.
  Type TForm1 = class(TForm)
  .
  .
  private
    MyArray: TMyArray;
  .
  .
  end;

implementation

procedure TForm1.ErzeugeArray;
begin
  for i:=0 to 9 do
    MyArray[i]:=i;
  TesteArray(@MyArray);
end;
und in Unit2:

Delphi-Quellcode:
Type
  TIntArray: array of Intger;

procedure TesteArray(p: Pointer);
begin
  for i:=0 to length(TIntArray(p))-1 do
    TuIrgendwasmit(TIntArray(p)[i]);
end;
So, das wird so sicherlich nicht funktionieren. Aber wie wäre es richtig und warum. Ich hab mich nun durch so einige Beispiele und Tutorials durch gelesen, aber ich raff das einfach nicht.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Bambini
(Gast)

n/a Beiträge
 
#2

AW: Array als Pointer übergeben

  Alt 28. Okt 2015, 13:01
Delphi-Quellcode:
procedure TForm1.ErzeugeArray;
begin
  for i:=0 to 9 do
    MyArray[i]:=i;
  TesteArray(@MyArray); // <--- nicht ganz richtig
end;
Eine festes Array of Integer ist <> einem Dynamische array of Integer.
Statt:

 TMyArray: Array [0..9] of Integer; eine TMyArray: Array of Integer; verwenden und diese mit Setlength() auf 10 setzen.

Geändert von Bambini (28. Okt 2015 um 13:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#3

AW: Array als Pointer übergeben

  Alt 28. Okt 2015, 13:08
TesteArray(@MyArray[1]);
Okay, aber warum die 1?
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Bambini
(Gast)

n/a Beiträge
 
#4

AW: Array als Pointer übergeben

  Alt 28. Okt 2015, 13:10
Meine erste Antwort war falsch. Habe diese geändert.
  Mit Zitat antworten Zitat
Sailor

Registriert seit: 20. Jul 2008
Ort: Balaton
112 Beiträge
 
Delphi 2010 Professional
 
#5

AW: Array als Pointer übergeben

  Alt 28. Okt 2015, 13:21
Du mußt p in TestArray derefenzieren.
  Mit Zitat antworten Zitat
SMO

Registriert seit: 20. Jul 2005
178 Beiträge
 
Delphi XE6 Professional
 
#6

AW: Array als Pointer übergeben

  Alt 28. Okt 2015, 13:31
Die 1 ist falsch.

Und zum Grundverständnis: es gibt Unterschiede zwischen statischen Arrays (TMyArray: Array [0..9] of Integer) und dynamischen Arrays (TIntArray: array of Integer). Die solltest du wenn möglich nicht hin und her casten, das kann zu Fehlern führen, wie in deinem Beispiel.

Kurz umrissen: statische Arrays sind ein zusammenhängender Speicherbereich. Die Länge ist nicht explizit vermerkt. Dynamische Arrays sind vergleichbar mit Strings und werden durch Compilermagic unterstützt (z.B. automatisches Freigeben von lokalen DynArray Variablen). Die DynArray Variablen sind implizite Pointer, die auf einen zusammenhängenden Speicherbereich zeigen (auf dem Heap). Direkt vor der Adresse, auf die gezeigt wird, stehen Metadaten, nämlich die Länge des Arrays sowie der RefCount.

Wenn du einen Cast wie "length(TIntArray(p))" machst, dann wird versucht, dieses Längenfeld zu lesen. Aber bei statischen Arrays existiert das gar nicht!


Um Arrays in Pointer umzuwandeln, benutze den Pointertyp, der zum Arrayelement passt. In deinem Beispiel also PInteger.

Delphi-Quellcode:
procedure TesteArray(p: PInteger; Count: Integer);
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
  begin
    TuIrgendwasmit(p^);
    Inc(p); // Pointer auf das nächste Element bewegen
  end;
end;

// oder mit der Direktive POINTERMATH können typisierte Pointer
// direkt wie statische Arrays benutzt werden!

{$POINTERMATH ON}
procedure TesteArray(p: PInteger; Count: Integer);
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
    TuIrgendwasmit(p[i]);
end;

// Aufruf:
var
  MyDynArray: array of Integer;
  MyStaArray: array [0..9] of Integer;

// geht, weil MyDynArray ein impliziter Pointer ist
TesteArray(PInteger(MyDynArray), Length(MyDynArray));

// geht NICHT, weil MyStaArray kein Pointer ist sondern ein 10*4 Bytes großer Speicherbereich
TesteArray(PInteger(MyStaArray), Length(MyStaArray));

// geht, weil sich an der Adresse von MyStaArray direkt der Speicherbereich mit den Elementen befindet
TesteArray(@MyStaArray, Length(MyStaArray));

// geht NICHT, weil sich an der Adresse von MyDynArray nur der implizite Pointer befindet!
TesteArray(@MyDynArray, Length(MyDynArray));


// geht IMMER, egal ob statisches oder dynamisches Array:
TesteArray(@MyStaArray[Low(MyStaArray)], Length(MyStaArray));
TesteArray(@MyDynArray[Low(MyDynArray)], Length(MyDynArray));

// bei dynamischen Arrays ist der niedrigste Index immer 0
// bei statischen Arrays kann man bei der Deklaration den niedrigsten Index auf beliebige Werte setzen,
// aber wenn man konsequent immer 0 benutzt, kann man natürlich schreiben:
TesteArray(@MyStaArray[0], Length(MyStaArray));
TesteArray(@MyDynArray[0], Length(MyDynArray));

Geändert von SMO (28. Okt 2015 um 14:15 Uhr)
  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
 
#7

AW: Array als Pointer übergeben

  Alt 28. Okt 2015, 13:48
Wie die anderen schon gesagt haben: Es ist ein Unterschied ob du ein statisches oder ein dynamisches Array hast:

Statische Arrays:
Delphi-Quellcode:
type
  PIntArray = ^TIntArray ;
  TIntArray = Array[0..9] of Integer;

procedure TForm1.FormCreate(Sender: TObject);
var MyArray: TIntArray;
    i: Integer;
begin
  for i:=0 to 9 do
    MyArray[i]:=i;

  TesteArray(@MyArray);
end;

procedure TForm1.TesteArray(P: Pointer);
var arr: TIntArray;
    i: Integer;
begin
  arr := PIntArray(P)^; // Oder TIntArray(P^)
  for i:=0 to 9 do
    Memo1.Lines.Add(IntToStr(arr[i]));
end;

Dynamische Arrays:
Delphi-Quellcode:
type
  TIntArray = Array of Integer;

procedure TForm1.FormCreate(Sender: TObject);
var MyArray: TIntArray ;
    i: Integer;
begin
  SetLength(MyArray, 10);
  for i:=0 to 9 do
    MyArray[i]:=i;

  TesteArray(Pointer(MyArray)); // Dyn. Arrays sind bereits Pointer
end;

procedure TForm1.TesteArray(P: Pointer);
var arr: TIntArray;
    i: Integer;
begin
  arr := TIntArray(P);
  for i:=0 to 9 do
    Memo1.Lines.Add(IntToStr(arr[i]));
end;
Du kannst diese beiden Array-Typen nicht so ohne weiteres mischen. Zumindest nicht auf "Pointer Ebene".

Wie über mir auch schon gezeigt wurde kannst du auch statt dem Array einen Pointer auf das erste Element des Arrays übergeben (bei beiden Array-Typen wäre das @Array[erster_index]).
Dann kannst du in deiner Methode über einen PInteger auf die Werte des Arrays zugreifen. Allerdings musst du der Methode dann zusätzlich die Anzahl der Elemente übergeben:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var MyArray: TIntArray;
    i: Integer;
begin
  SetLength(MyArray, 10);
  for i:=0 to 9 do
    MyArray[i]:=i;

  TesteArray(@MyArray[0], Length(MyArray)); // Geht bei statischen Arrays genauso
end;

procedure TForm1.TesteArray(P: PInteger; Anzahl: Integer);
var i: Integer;
begin
  for i:=0 to Anzahl-1 do
  begin
    Memo1.Lines.Add(IntToStr(P^));
    inc(P); // Pointer auf das nächstes Element des Arrays setzen
  end;
end;
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."

Geändert von Neutral General (28. Okt 2015 um 13:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#8

AW: Array als Pointer übergeben

  Alt 28. Okt 2015, 14:31
Vielen Dank. Ihr habt mir sehr weitergeholfen. Und Dank der Erklärung dabei habe ich das auch verstanden.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#9

AW: Array als Pointer übergeben

  Alt 28. Okt 2015, 15:45
Ein Pointer ist eine Speicheradresse, nicht mehr und nicht weniger!
Falls Du eine Definition hast wie
Delphi-Quellcode:
type
 ta = Array [23..24] of Byte;
 tpa = ^ta;
dann wird der Inhalt des Speichers auf den der Pointer zeigt als Array [23..24] of Byte; interpretiert.
Zeigt der Pointer auf einen String
Delphi-Quellcode:
var
  p : tpa
  s : string[255];
...

p:=@s;
so wird der Speicherinhalt immer noch als Array [23..24] of Byte; interpretiert.

somit ist "Array als Pointer übergeben" nicht möglich. Möglich wäre es die Adresse eines Arrays zu übergeben wobei Du bei Dynamischen Array zwischen dem Inhalt des Arrays @Myarray[0] und der Array-Variablen @MyArray unterscheiden mußt. Bei statischen Arrays ist @MyArray=@MyArray[0]

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#10

AW: Array als Pointer übergeben

  Alt 28. Okt 2015, 16:11
somit ist "Array als Pointer übergeben" nicht möglich. Möglich wäre es die Adresse eines Arrays zu übergeben wobei Du bei Dynamischen Array zwischen dem Inhalt des Arrays @Myarray[0] und der Array-Variablen @MyArray unterscheiden mußt. Bei statischen Arrays ist @MyArray=@MyArray[0]

Gruß
K-H
Okay, bis eben dachte ich, ich hätt's verstanden Und dann machst du sowas

Ich dachte eigentlich immer im Pointer steht die Adresse?
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  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 08:32 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