Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Pointer kann nicht freigegeben werden? (https://www.delphipraxis.net/89707-pointer-kann-nicht-freigegeben-werden.html)

Nuclear-Ping 4. Apr 2007 14:44


Pointer kann nicht freigegeben werden?
 
Hallo,

irgendwie hab ich grad Tomaten auf den Augen oder so, aber ich hab hier ein Problem was ich nicht so recht verstehe und auch nicht direkt gelöst bekomme:
Delphi-Quellcode:
procedure TQuantisScannerGIF.StartScanner (DurationMs: Cardinal = 0);
var
  qBuffer: ^Byte;
  a, b, ReqBytes, fh, rd: Integer;
  BitArr: TBitArray;
begin
  if (quantisCount = 0) or (quantisBoardReset (0) <> 0) then
    begin
      BreakScan := TRUE;
      MessageDlg ('Could not reset LQR.', mtError, [mbOK], 0);
      Exit;
    end;

  LocalBitsValCount[0] := 0;
  LocalBitsValCount[1] := 0;

  ReqBytes := round (((DurationMs / 1000) * 4096000) / 8);
  GetMem (qBuffer, ReqBytes);
  try
    rd := quantisRead (0, Pointer (qBuffer), ReqBytes);
    if (rd <> ReqBytes) then
      begin
        BreakScan := TRUE;
        MessageDlg (Format ('Error reading LQR.' + #13#10 +
                            'Requested: %d' + #13#10 +
                            'Read: %d', [ReqBytes, rd]), mtError,
                    [mbOK], 0);
        Exit;
      end;

    for a := 0 to rd - 1 do
      begin
        BitArr := ByteToBitArr (qBuffer^);
        inc (qBuffer);

        for b := 0 to 7 do
          inc (LocalBitsValCount[Byte (BitArr[b])]);
      end;

    inc (TotalBitsValCount[0], LocalBitsValCount[0]);
    inc (TotalBitsValCount[1], LocalBitsValCount[1]);
  finally
    FreeMem (qBuffer);
  end;
end;
Ich erhalte bei "FreeMem (qBuffer);" eine Zugriffsverletzung. Kommentiere ich "inc (qBuffer);" aus, erhalte ich keine Zugriffsverletzung. :gruebel: Aber warum?!? Speicher wurde reserviert, die Grenzen (0 to rd - 1) werden eingehalten und logischerweise muss der Speicher auch wieder freigegeben werden. Selbst wenn ich alles in der Schleife (for a := 0 to rd - 1 ...) auskommentiere und nur "inc (qBuffer)" drinsteht, knallts.
Kommentiere ich FreeMem aus, erhalte ich auch keine AVs mehr, aber dann erzählt mir der Leak-Report vom FastMM Romane.

Ich hab das jetzt erstmal mit einem Array of Byte gelöst, aber ich würde ich Version über Pointer schon vorziehen.

Grüße,

Mario

SirThornberry 4. Apr 2007 14:47

Re: Pointer kann nicht freigegeben werden?
 
Das ist korrekt. Du forderst Speicher an und bekommst die Adresse zurück geliefert des angeforderten Speichers. Diese Adresse änderst du (incrementierst) und sagst dann der Speicher an der neuen Adresse soll frei gegeben werden. Aber es wurde nie ein Speicherblock reserviert welcher an dieser Adresse los geht. Demzufolge kann da auch nichts wieder frei gegeben werden.

Bildlich kannst du dir das wie folgt vorstellen:
- Du lässt dich mit dem Taxi nach OrtA fahren und merkst dir die Nummer des Taxis (Nummer 375)
- Dann läufst du von OrtA nach OrtB
- Dort rufst du die Taxizentrale an und sagst du willst von OrtB abgeholt werden wo Taxi 375 dich abgeliefert hat.
- Die Verwirrung ist groß weil Taxi 375 niemals jemanden in OrtB abgeliefert hat und somit jetzt auch nicht weiß wo in OrtB jemand abgeholt werden soll.

Nuclear-Ping 4. Apr 2007 15:50

Re: Pointer kann nicht freigegeben werden?
 
Ok, alles klar.
Delphi-Quellcode:
{...}

  GetMem (qBuffer, ReqBytes);
  qAddr := Integer (qBuffer);

  {...}
  finally
    qBuffer := Pointer (qAddr);
    FreeMem (qBuffer);
  end;
Das funktioniert nun. Danke, dass du mich mit der Nase draufgedrückt hast. :mrgreen:

DP-Maintenance 6. Apr 2007 14:13

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Object-Pascal / Delphi-Language" verschoben.
Es geht um Delphi.

SirTwist 6. Apr 2007 16:45

Re: Pointer kann nicht freigegeben werden?
 
Autsch!

Wozu sind die Umwandlungen nach Integer und wieder zurück? Du willst einen Pointer speichern, also nimm dafür bitte auch eine Pointer-Variable. Es sieht halt schöner aus ;-) und es könnte auch auf zukünftigen Prozessorgenerationen noch funktionieren.

Gruß,
Michael

grenzgaenger 7. Apr 2007 08:33

Re: Pointer kann nicht freigegeben werden?
 
Zitat:

Zitat von Nuclear-Ping
Ok, alles klar.
Delphi-Quellcode:
{...}

  GetMem (qBuffer, ReqBytes);
  qAddr := Integer (qBuffer);

  {...}
  finally
    qBuffer := Pointer (qAddr);
    FreeMem (qBuffer);
  end;
Das funktioniert nun. Danke, dass du mich mit der Nase draufgedrückt hast. :mrgreen:

komm, das da oben vergiss mal. das macht keinen sinn. vielmehr interessiert was du hier machst:
Delphi-Quellcode:
    for a := 0 to rd - 1 do
      begin
        BitArr := ByteToBitArr (qBuffer^);
        inc (qBuffer);
sollte das nicht inc(qBuffer^) heissen? sonst kannst du ja nix incrementieren. die addy ist tabu.

wenn du jedoch das ganze durchlaufen möchtest, kannst dir ja 'n pointer schaffen und es durchlaffen, geht in etwa so:
Delphi-Quellcode:
var p: pointer;
begin ....
 p := @qBuffer;
 for ...
  bittarr := bytetobitarr(byte(p^));
  inc(p);
damit wäre p deine laufvariable, in deinem reservierten speicherbereich, der über getmen an qBuffer zugewiesen wurde. qbuffer bleibt unverändert und du durchläufst nur den reservierten speicher, mit p. musst aber selbst dafür sorgen, dass du nicht über die grenzen hinausliesst. ganze ist ungetestet sollte aber so, plus/minus ein, zwei kleinigkeiten funktionieren. ausserdem kannst du mal unter den stichwort pointerarithmetik gucken ob du zusätzliches findest...

<HTH>

Flocke 7. Apr 2007 13:07

Re: Pointer kann nicht freigegeben werden?
 
Zitat:

Zitat von grenzgaenger
sollte das nicht inc(qBuffer^) heissen? sonst kannst du ja nix incrementieren.

Ich denke nicht. Er möchte hier den C-Ausdruck "*qBuffer++" nach Delphi übersetzen.

Zitat:

Zitat von grenzgaenger
die addy ist tabu.

Wieso sollte sie das sein? Er hat sie doch in "qAddr" gesichert (obwohl ziemlich umständlich).

Zitat:

Zitat von grenzgaenger
wenn du jedoch das ganze durchlaufen möchtest, kannst dir ja 'n pointer schaffen und es durchlaffen

"qBuffer" ist doch schon ein Pointer.

grenzgaenger 7. Apr 2007 19:32

Re: Pointer kann nicht freigegeben werden?
 
tja, er braucht halt einen anker, da er dynamisch speicher reserviert, muss er bei der freigabe mitteilen welcher speicher wieder freigegeben werden soll. ansonsten könnt er natürlich mit qBuffer machen was er möchte...

anbei noch 'n kleines testprogram mit 'n increment
Delphi-Quellcode:
program Project1;
{$APPTYPE CONSOLE}
uses sysutils;
var
 i: byte;
 x, b: ^byte;
begin
 getmem(b, 10);
 x := b;
 for i := 0 to 9 do
 begin
  x^ := i;
  inc(x);
 end;

 //testausgabe
 x := b;
 for i := 0 to 9 do
 begin
  writeln(x^);
  inc(x);
 end;
 freemem(b);
 readln;
end.


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