AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Ich und die Pointer... die nicht so wollen wie ich
Thema durchsuchen
Ansicht
Themen-Optionen

Ich und die Pointer... die nicht so wollen wie ich

Ein Thema von turboPASCAL · begonnen am 20. Sep 2007 · letzter Beitrag vom 21. Sep 2007
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#1

Ich und die Pointer... die nicht so wollen wie ich

  Alt 20. Sep 2007, 18:39
Hi,

Delphi-Quellcode:
type
  TByteArray = array of Byte;
  PByteArray = ^TByteArray;

var
  B: PByteArray;

begin
  new(b);

  setlength(B^, 100 + 1);

  B^[10] := 255;

  writeln(B^[10]);

  dispose(B);
  readln;
end.
... das stimmt doch so oder nicht ?

Das eigentliche Problem ist das ich immer bei diesem Code eine AV erhalte:

Delphi-Quellcode:
procedure SaveBitmap32AsTGAFile(bmp32: TBitmap32; TGAFileName: String);
var
  fs: TFileStream;
  tgaHeader : TTGAFileHeader;
  DataArray: Array of DWORD;
  DataSize, n: DWORD;
begin
  ZeroMemory(@tgaHeader, sizeof(tgaHeader));
  tgaHeader.imagetype := 2;
  tgaHeader.width := bmp32.Width;
  tgaHeader.height := bmp32.Height;
  tgaHeader.pixeldepth := $20; // 32 Bit
  tgaHeader.descriptor := $08; // Bits 00001000 = 8 = $08

  DataSize := bmp32.Width * bmp32.Height;
  SetLength(DataArray, DataSize - 1);

  ZeroMemory(@DataArray, sizeof(DataArray));

  // Swap Bitmap top / bottom

  // >>--> AV / Berechsüberprüfung
  for n := bmp32.Width * bmp32.Height-1 downto 0 do
    DataArray[n] := bmp32.bits^[n];
  // <--<<

  fs := TFilestream.Create(TGAFileName, fmCreate);
  try
    fs.Seek(soFromBeginning, 0);
    fs.Write(tgaHeader, SizeOf(tgaHeader));
    fs.Write(DataArray[0], DataSize);
  finally
    FreeAndNil(fs);
  end;

  SetLength(DataArray, 0);
end;
Irgendwie will es nicht wie ich es will. Was ist der Fehler ?



( der komplette Vorgängerquelltext )
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Ich und die Pointer... die nicht so wollen wie ich

  Alt 20. Sep 2007, 18:43
Zitat:
ZeroMemory(@DataArray, sizeof(DataArray));
Hier bewirkst du, dass du dein Array nicht mehr nutzen kann. Und beim Zugriff auf das Array knallt es natürlich. Ich glaube, du meinst ZeroMemory(@DataArray[0], length(DataArray)*sizeof(DWord));
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#3

Re: Ich und die Pointer... die nicht so wollen wie ich

  Alt 20. Sep 2007, 19:07
  • Dynamische Arrays landen auf dem Heap und sind damit automatisch genullt.
  • Die Dereferenzierung von Bits sollte unnötig sein, siehe auch das Beispiel in der Doku.
  • Was hat der obere mit dem unteren Code zu tun / Wo sind die Zeiger ?
  • Dreht der Code das Bitmap wirklich um? Ich hätte in der Schleife einfach den n-ten mit dem (Width * Height - n)-ten Pixel getauscht, dann ist auch das zweite Array überflüssig.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#4

Re: Ich und die Pointer... die nicht so wollen wie ich

  Alt 20. Sep 2007, 19:15
Delphi-Quellcode:
type
  TByteArray = array of Byte;
  PByteArray = ^TByteArray;

var
  B: PByteArray;

begin
  new(b);

  setlength(B^, 100 + 1);

  B^[10] := 255;

  writeln(B^[10]);

  dispose(B);
  readln;
end.
Nein, das stimmt so nicht. Lass den PByteArray-Kram weg. SetLength regelt die Alloziierung fuer das TByteArray. Die Dealloziierung aller "array of"-Variablen geschieht heimlich und automatisch.
Delphi-Quellcode:
type
  TByteArray = array of Byte;
var
  B: TByteArray;
begin
  // Hier wird B von Delphi heimlich auf nil initialisiert
  // SetLength alloziiert 101 Elemente (Bytes).
  setlength(B, 100 + 1);

  B[10] := 255;

  writeln(B[10]);
  readln;
  // Hier gibt Delphi das alloziierte array heimlich frei
end.
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#5

Re: Ich und die Pointer... die nicht so wollen wie ich

  Alt 20. Sep 2007, 22:16


Äh, nein. Ich habe mich wohl etwas schräg ausgedrückt. Der obere Teil des Codes war eine
Überlegung (so 'n kleiner Test) von mir zum unteren Code den ich Verwenden will um ein
Bitmap vertikal gespiegelt in eine TGA-Datei zu schreiben.

bmp32.bits ist ein Pointer auf ..., nein falsch ethält die Adresse eines Array of Cardinal
(DWORD).

Die Graphics32 leute haben das so gebaut:

Delphi-Quellcode:
type
  PColor32 = ^TColor32;
  TColor32 = type Cardinal;

  PColor32Array = ^TColor32Array;
  TColor32Array = array [0..0] of TColor32;
  TArrayOfColor32 = array of TColor32;
bmp32.bits ist als PColor32Array definiert.

Was ich auch Anstelle, es kommt eine AV. ( Berichs- und Überlaufüberprüfung sind an)

PS.:
Ich konnte es über "Scanline" machen, macht ja aber fasst jeder.
bmp32.FlipVert(nil); bitte nicht vorschlagen
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#6

Re: Ich und die Pointer... die nicht so wollen wie ich

  Alt 20. Sep 2007, 22:34
Delphi-Quellcode:
// 1.
type
  TByteArray = array of Byte;

// 2.
  PByteArray = ^TByteArray;

// 3.
type
  TByteArray = array[MaxInt] of Byte;
  PByteArray = ^TByteArray;
beide Typdeklarationen definieren was komplett Anderes. Das 1. ist ein dynamsiches Array of Bytes. Dieses ist ein komplexer Datentyp der zwar ein Array darstellt aber intern ein Zeiger auf einen Record der ein Array enthält darstellt. Der Typ bei 2. definert also wenn man es so will einen Zeiger auf einen Zeiger.

Der Typ bei 3. ist ein Array auf Bytes mit fester Größe. Erst durch den Typ PByteArray der auf ^TByteArray referenziert ist ein Zeigertyp direkt in einen Speicherbereich der als Byte Array interpretiert werden soll. Dies ist die alte Schreibweise in der man dann auch explizit solche Speicherbereiche allozieren und deallozieren muß. Das sollte erfolgen mit GetMem() und FreeMem() aber nicht mit New() und Dispose(). Die letzeren beiden hat man verwendet um komplexere Datentypen zu allozieren/deallozieren, zb. Records oder Objekte ganz alten Typus.

Du vermischt also in deinem Code zwei komplett unterschiedliche Datentypen mit den falschen Methoden und Zugriffen darauf.
Dieses Wirrwarr entstand durch die Evolution der Delphi/PASCAL Sprache mit der Zeit.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#7

Re: Ich und die Pointer... die nicht so wollen wie ich

  Alt 20. Sep 2007, 22:37
Welche Exception tritt denn nun auf - AV, Bereichsprüfung oder beides? Bei der Bereichsprüfung darfst du dich nicht wundern, wenn du mit einem "array[0..0]" arbeitest, am Besten also ausschalten oder - was wohl sauberer wäre - einen PColor32-Zeiger per @bmp.Bits[0] holen und dann inkrementieren.
Und wie gesagt, in der Doku fehlt die Dereferenzierung ebenfalls:
Delphi-Quellcode:
var

  P: PColor32Array;

begin

  P := Bitmap32.Bits;

  for I := 0 to Bitmap32.Width * Bitmap32.Height - 1 do

    P[I] := Gray32(Random(255)); // fill with a random grayscale noise

end;
Das sollte aber alles nicht zur AV führen. Außer dem bereits erwähnten ZeroMemory fällt mir in dem Zusammenhang nur noch eines auf: Dein DataArray ist um ein Item zu kurz.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#8

Re: Ich und die Pointer... die nicht so wollen wie ich

  Alt 20. Sep 2007, 22:44
Hallo,

Delphi-Quellcode:
  DataSize := bmp32.Width * bmp32.Height;
  SetLength(DataArray, DataSize - 1); // <--- Warum hier -1 ??? Damit fehlt Dir ein Element -> AV weiter unten

  ZeroMemory(@DataArray, sizeof(DataArray));
Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#9

Re: Ich und die Pointer... die nicht so wollen wie ich

  Alt 20. Sep 2007, 23:26
Ja, das Setlength -1 ist ein tippfehler durch die Rumprobiererei...

Ihr könnt es ja selbst mal testen, vorrausgesetzt ihr habt dei gr32 installiert:
Angehängte Dateien
Dateityp: zip tgasavetest_124.zip (70,8 KB, 3x aufgerufen)
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Benutzerbild von x000x
x000x

Registriert seit: 21. Jan 2004
Ort: Bei Hamburg
308 Beiträge
 
Delphi XE2 Professional
 
#10

Re: Ich und die Pointer... die nicht so wollen wie ich

  Alt 21. Sep 2007, 01:06
Moin moin,
Khabarakh hat hier schon das Problem erkannt.
Zitat von Khabarakh:
Bei der Bereichsprüfung darfst du dich nicht wundern, wenn du mit einem "array[0..0]" arbeitest
...
einen PColor32-Zeiger per @bmp.Bits[0] holen und dann inkrementieren.
Das sollte so funktionieren.
Delphi-Quellcode:
  // Bild "flippen"
  // >>--> AV / Berechsüberprüfung
  for n := 0 to bmp32.Width * bmp32.Height-1 do begin
       DataArray[n] := P[0];
       Inc(P);
  end;
Peter
-= Gruss Peter =-
-= alias x000x =-
  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:13 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