Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Pointerinhalt verändern (https://www.delphipraxis.net/48810-pointerinhalt-veraendern.html)

Jasmine 30. Jun 2005 18:01


Pointerinhalt verändern
 
Hallo zusammen,

bin neu hier und programmiere erst seit kurzem.

Ich habe ein Verständnisproblem mit Pointern und es wäre sehr nett, wenn ein
paar von euch lieben Spezialisten mir helfen könnte :)

Ich habe zwei Pointer deklariert:

var
buffer : PChar;
copybuffer : PChar;

Ihnen dann Speicher zugewiesen :

buffer:=Pchar(AllocMem(1024));
copybuffer:=Pchar(AllocMem(1024));

Dann aus einem File in einen gelesen :

FileRead(FH,buffer^,50);

Nun kopiert :

copybuffer^:=buffer^;

Nun möchte ich ähnlich wie bei arrays copybuffer[x]:=copybuffer[x] + vari[x]
vom ersten Wert bis zu einem bestimmten den Inhalt verändern, in diesem Fall die
Variable vari[x] dazu addieren.

Jedoch:

for i:=1 to 50 do copybuffer^[i]:=copybuffer^[i]+vari[i];

funktioniert nicht !

Über ein paar Tips würde ich mich sehr freuen.

Danke,

Jasmine



:hi:

Delphi-Freak 30. Jun 2005 18:12

Re: Pointerinhalt verändern
 
Hi!

:hi: Herzlich willkommen in der DP! :hi:


Könnte es vielleicht über
Delphi-Quellcode:
for i:=1 to 50 do copybuffer[i]:=copybuffer[i]+vari[i];
funktionieren (PChar ist ja nicht ein »Standard-Pointer«, sondern etwas anders, glaube ich... :gruebel: )
oder sonst vielleicht mit
Delphi-Quellcode:
for i:=1 to 50 do copybuffer[i]^:=copybuffer[i]^+vari[i];
Sind nur zwei spontane Ideen, ist aber eine gute Frage



LG, Delphi-Freak

DP-Maintenance 30. Jun 2005 18:19

DP-Maintenance
 
Dieses Thema wurde von "alcaeus" von "Programmieren allgemein" nach "Object-Pascal / Delphi-Language" verschoben.
Geht wohl mehr in die Richtung von Object Pascal ;)

brechi 30. Jun 2005 18:26

Re: Pointerinhalt verändern
 
Delphi-Quellcode:
for i := 0 to 50-1 do
  pbyte(integer(copybuffer)+i)^ := pbyte(integer(copybuffer)+i)^+vari[i];
oder du machst:

Delphi-Quellcode:
type tbla: array[0..0] of byte;
     pbla: ^tbla;
     bla: pbla;
begin
  bla := copybuffer;
  for i := 0 to 50-1 do
    bla[i]^ := bla[i]^+var[i];
end;

Jasmine 30. Jun 2005 18:55

Re: Pointerinhalt verändern
 
Das ging aber schnell, danke :-D

@Delphi-Freak

klappt leider nicht

@brechi

Danke.

Aber woher nehme ich pbyte ? Locale Variabel als Byte deklariert ?

var
pbyte : byte;

Compiler gibt Fehlermeldung : Missing operator or semicolon aus !

Jasmine

Delphi-Freak 30. Jun 2005 19:05

Re: Pointerinhalt verändern
 
pbyte dürfte eine Funktion sein, sowie z.B. die Funktion PChar(). Wahrscheinlich brauchst du dafür irgendwelche Units in den Uses - nur weiß ich auch nicht welche, ich lese diesen Fuktionsnamen (wenn es überhaupt einer ist) zum ersten Mal... Brechi kann dir da wahrscheinlich besser helfen :?

LG, ich

brechi 30. Jun 2005 19:06

Re: Pointerinhalt verändern
 
type pbyte = ^byte;

sollte delphi aber kennen, weils in der windows.pas steht
also einfach nix deklarieren

edit:

pchar ist nichts anderes als nen ^char;
also nen pointer auf nen char (array)

gibt auch pinteger etc. kommt halt drauf an was du amchen willst aber nen + funktioniert nur auf zahlbasis

d.h. du kannst nicht 2 chars addieren sondern nur 2 bytes

Delphi-Freak 30. Jun 2005 19:12

Re: Pointerinhalt verändern
 
Bedeutet das, dass wenn man zwei Typen
Delphi-Quellcode:
type
  MyType: Array of Byte;
  PMyType: ^MyType;
hat, dass es dann automatisch die »Funktion« PMyType gibt, um einen Pointer zu erzeugen? :gruebel:


mfg


[Edit]Tschuldigung, dass das jetzt etwas OT wird :oops: [/Edit]

brechi 30. Jun 2005 19:16

Re: Pointerinhalt verändern
 
pmytype ist dann einfach nur nen pointer, mehr nicht.
aber wenn du den veränderst mit mytype^ ändert delphi das dann jenachdem ab worauf es zeigt

d.h. nen pbyte(addr)^ := 1; würde nur das byte an der addreses ändern
nen pinteger(addr)^ := 1; würde 4 bytes ändern
usw.

wenn du nen ^array hast dann musst du noch nen index angeben

Khabarakh 30. Jun 2005 19:34

Re: Pointerinhalt verändern
 
Das war IMHO nicht Delphi-Freaks Frage.
PMyType ist keine neue Funktion, sondern einfach ein Typecast, den es ja automatisch für jeden Typ gibt.

marabu 1. Jul 2005 06:13

Re: Pointerinhalt verändern
 
@Jasmine:

Delphi-Quellcode:
uses
  Windows;
 
const
  CBUFSIZE = 1024;

var
  buffer, src: PByte;
  copyBuffer, tgt: PByte;

begin
  buffer := Pchar(AllocMem(CBUFSIZE));
  copybuffer := Pchar(AllocMem(CBUFSIZE));
  FileRead(FH, buffer^, 50);

  src := buffer;
  tgt := copyBuffer
  for i := 1 to 50 do begin
    tgt^ := src^ + vari[i];
    Inc(src); // Zeiger um eine Stelle weiterrücken
    Inc(tgt);
  end;
end;
Grüße vom marabu

SirThornberry 1. Jul 2005 07:33

Re: Pointerinhalt verändern
 
von welchem Typ ist dein "vari"? wenn es ebenso ein PChar ist könntest du mit move arbeiten, dies sollte so ziemlich das schnellste sein
Delphi-Quellcode:
move(vari^, copybuffer^, 50);
wenn du dich für die andere Variante mit der Schleife entscheidest solltest du daran denken das der Schleifendurchlauf bei 0 beginnen sollte weil PChar 0 bassierend ist und nicht wie String 1 basierend.
Bei PChar würdest du also mit
Delphi-Quellcode:
copybuffer[1] := 'a';
das zweite zeischen schreiben

barf00s 1. Jul 2005 08:50

Re: Pointerinhalt verändern
 
tuts da nich auch einfach nen

Delphi-Quellcode:
Move(pointer(ziel)^, pointer(quelle)^, groesseinbytesofquelle);

Olli 1. Jul 2005 09:12

Re: Pointerinhalt verändern
 
Zitat:

Zitat von Delphi-Freak
Bedeutet das, dass wenn man zwei Typen
Delphi-Quellcode:
type
  MyType: Array of Byte;
  PMyType: ^MyType;
hat, dass es dann automatisch die »Funktion« PMyType gibt, um einen Pointer zu erzeugen? :gruebel:

Nein, es bedeutet, daß man verschiedene Typen ineinander "konvertieren" kann. Das nennt sich dann "Typecast". Diese Methode gibt es in verschiedenen Sprachen und sie ist an verschiedenen Stellen unabdingbar - insofern deine benutzte Sprache eine halbwegs rigide Typüberprüfung während der Kompilation vornimmt.

Beispiel:
Delphi-Quellcode:
var
  Int32: Integer; // vorzeichenbehaftet 32bit
  UInt32: DWORD; // vorzeichenlos 32bit
  Bla: PChar; // Pointer auf nullterminierte Zeichenkette
begin
  Int32 := -1;
  UInt32 := DWORD(Int32); // vorzeichenbehaftet nach vorzeichenlos konvertieren
  // Hier ist (UInt32 == $FFFFFFFF)
  Bla := 'Ottokar das Früchtchen';
  UInt32 := DWORD(Bla); // Pointer nach "unsigned integer"
  UInt32 := UInt32 + 4;
  Bla := PChar(UInt32);
  // Hier zeigt Bla auf 'kar das Früchtchen'! Wir sind nämlich 4 Bytes vorgerückt
end;
String(PCharVariable) und PChar(StringVariable) gehören ebenfalls in diese Kategorie, haben aber noch eine tiefere Bedeutung ("compiler magic")!

Jasmine 1. Jul 2005 10:17

Re: Pointerinhalt verändern
 
Hallo ihr Lieben,

vielen Dank für die vielen Tips.

Ich habe verstanden, dass man einen PChar Pointer nicht mit Byte oder PByte
verrechnen kann, wie ich es versuchte, da mein vari :
array[1..100] of byte
ist.

Im Prinzip will ich von einem File in einen buffer schreiben, diesen mit Werten meines
Arrays vari verrechnen und den geänderten Buffer wieder in ein File schreiben.

Die Idee von maribu war schon nicht schlecht, allerdings gibt es in dem Beispielcode
auch einen Konflikt zwischen der Deklaration von PByte und dann der Speicherreservierung
Pchar(AllocMem(CBUFSIZE)). Wenn ich hier auch mit PByte reserviere, startet mein Programm,
jedoch stürzt es an der Stelle ab und gibt ein Exeption mit Pointer invalid operation oder
so aus.

Werde mal die Idee von brechi :

Delphi-Quellcode:
type tbla: array[0..0] of byte;
     pbla: ^tbla;
     bla: pbla;
begin
  bla := copybuffer;
  for i := 0 to 50-1 do
    bla[i]^ := bla[i]^+var[i];
end;
ausprobieren.

Würde mich über weitere Hilfe sehr freuen und Danke für eure Geduld.

Jasmine :cat:

marabu 1. Jul 2005 13:12

Re: Pointerinhalt verändern
 
Hallo Jasmine,

Zitat:

Zitat von Jasmine
Die Idee von maribu war schon nicht schlecht, allerdings gibt es in dem Beispielcode auch einen Konflikt zwischen der Deklaration von PByte und dann der Speicherreservierung
Pchar(AllocMem(CBUFSIZE)).

Weg mit dem unnützen type cast - und vergess nicht später deinen dynamisch angeforderten Speicher wieder frei zu geben.

marabu

Jasmine 1. Jul 2005 13:47

Re: Pointerinhalt verändern
 
Also ist schon seltsam mit PChar und PByte.

Einen Pointer mit PByte deklariert kann ich nicht mit :

copybuffer[i]^:=copybuffer[i]^+vari[i]; oder

copybuffer^[i]:=copybuffer^[i]+vari[i]; oder

copybuffer[i]:=copybuffer[i]+vari[i]; setzen. (vari:array[1..100] of integer)

Wenn ich allerdings einen PChar Pointer nehme klappt es,
allerdings kann ich dann kein Integer / Byte Wert in vari[i] nehmen.

Also habe ich den Wert erst mit integer(copybuffer[i]) in eine Zwischenvaliable a als
Integer deklariert gelesen, dann meinen vari[i] dazuaddiert, und wieder über
copybuffer[i]:=var(a) in den Speicher zurückgeschrieben und es funktioniert.

Ist vielleicht nicht sehr elegant, aber läuft.

Mich würde jetzt brennend interessieren, warum ich dasselbe nicht mit einem PByte deklarierten
Pointer machen kann. Vielleicht weil PByte nicht gleich Integer ist ? Ich werde mal einen Pointer mit PInteger versuchen.

Danke trotzdem, habt mir sehr geholfen.

Jasmine :hello:

SirThornberry 1. Jul 2005 16:01

Re: Pointerinhalt verändern
 
wenn du eine Datei verändern willst kannst du auch gleich TFileStream nehmen und dann mit YourFileStreamInstanz.Write den buffer direkt in die Datei schreiben, das müsste dir ne Menge arbeit spaaren und sollte auch von der performance her recht flott sein.

brechi 1. Jul 2005 17:51

Re: Pointerinhalt verändern
 
wenn du nen integer nimmst musst du auch nen pinteger nehmen anstatt nen pbyte...
oder du musst halt den integer mit byte(vari[i]) abschneiden

Delphi-Freak 1. Jul 2005 19:16

Re: Pointerinhalt verändern
 
Zitat:

Zitat von Olli
Zitat:

Zitat von Delphi-Freak
Bedeutet das, dass wenn man zwei Typen
Delphi-Quellcode:
type
  MyType: Array of Byte;
  PMyType: ^MyType;
hat, dass es dann automatisch die »Funktion« PMyType gibt, um einen Pointer zu erzeugen? :gruebel:

Nein, es bedeutet, daß man verschiedene Typen ineinander "konvertieren" kann. Das nennt sich dann "Typecast". Diese Methode gibt es in verschiedenen Sprachen und sie ist an verschiedenen Stellen unabdingbar - insofern deine benutzte Sprache eine halbwegs rigide Typüberprüfung während der Kompilation vornimmt.

Beispiel:
Delphi-Quellcode:
var
  Int32: Integer; // vorzeichenbehaftet 32bit
  UInt32: DWORD; // vorzeichenlos 32bit
  Bla: PChar; // Pointer auf nullterminierte Zeichenkette
begin
  Int32 := -1;
  UInt32 := DWORD(Int32); // vorzeichenbehaftet nach vorzeichenlos konvertieren
  // Hier ist (UInt32 == $FFFFFFFF)
  Bla := 'Ottokar das Früchtchen';
  UInt32 := DWORD(Bla); // Pointer nach "unsigned integer"
  UInt32 := UInt32 + 4;
  Bla := PChar(UInt32);
  // Hier zeigt Bla auf 'kar das Früchtchen'! Wir sind nämlich 4 Bytes vorgerückt
end;
String(PCharVariable) und PChar(StringVariable) gehören ebenfalls in diese Kategorie, haben aber noch eine tiefere Bedeutung ("compiler magic")!

Aha, das erklärt einiges, Danke :thumb:

LG, Delphi-Freak


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz