Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Für diesen Vorgang ist nicht genügend Speicher verfügbar (https://www.delphipraxis.net/961-fuer-diesen-vorgang-ist-nicht-genuegend-speicher-verfuegbar.html)

Stephan 3. Okt 2002 17:17

Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Daniel,

mal ganz dumm gefragt, wann und wie muss ich wieder freigeben?

ich hab mal memproof über google gefunden und ausgeführt. Das Resultat hab ich hier angehängt.
Sobald ich allerdings mein Programm geschlossen habe erscheinen in MemProof haufenweise Meldungen die so lauten: GetMem allocates memory from the RTL memory manager and returns a pointer. The returned pointer must be freed with FreeMem.

viele grüße

Stephan

d3g 3. Okt 2002 17:28

Hi Stephan,

du musst immer etwas freigeben, wenn du Speicher reservierst. Da gibt es bestimmte Befehlspaare.
  • Zu jedem TObject.Create muss auch ein TObject.Free. Wichtig ist, dass du nicht vor dem freigeben der Variable ein anderes Objekt zuweist:
    Code:
    var
      a: array[1..100] of TStringList;
      i: Integer;

    // ...

    for i := 1 to 100 do
      a[i] := TStringList.Create;
    // Arbeiten mit den Stringlists
    for i := 1 to 100 do
      a[i] := TStringList.Create;
    Die ersten 100 Stringlists sind verloren, du wirst nie wieder auf sie zugreifen können. Richtig wäre folgendes:
    Code:
    for i := 1 to 100 do
      a[i] := TStringList.Create;
    for i := 1 to 100 do
      a[i] := TStringList.Free;
    // Arbeiten mit den Stringlists
    for i := 1 to 100 do
      a[i] := TStringList.Create;
    for i := 1 to 100 do
      a[i] := TStringList.Free;
  • Zu jedem GetMem/StrAlloc etc. muss auch ein FreeMem/StrDispose etc.

    Auch hier gilt: wenn du einem Pointer eine neue Speicherstelle zuweist, dann wars das.

    Tödlich:
    Code:
    var
      p: Pointer;

    // ...

    GetMem(p, 10240); // 10 kb Speicher
    // Arbeiten mit p
    GetMem(p, 20480); // 20 kb
    Richtig:
    Code:
    GetMem(p, 10240); // 10 kb Speicher
    FreeMem(p);
    // Arbeiten mit p
    GetMem(p, 20480);
    FreeMem(p);
MfG,
d3g

Daniel B 3. Okt 2002 17:28

Hi Stephan,

nun, mit Canvas zeichnest Du ja irgendwas. Vielleicht ein Bitmap?!
Du hast uns nicht gesagt was und wie Du zeichnest.
Wenn man zum Bleistift mit Canvas in ein Bitmap zeichnet, Bitmap.Create o.ä., dann muss man es am Schluss wieder mit Bitmap.Free; freigeben, sonst wird der ganze Arbeitspeicher so zugemüllt, bis nichts mehr da ist. Nur so als Beispiel.
Code wäre nicht schlecht. Kann man bestimmt mehr sagen.

Grüsse, Daniel :hi:

Stephan 3. Okt 2002 18:10

Hi,

ja, ich zeichne in eine paintbox direkt aufs canvas. Bei dem Befehl bei dem der Fehler kommt werden alle Objekte in der Datenbank neu aufs canvas gezeichnet. Dazu verwend ich folgendes:

paintbox1.repaint;

dann kommt die Schleife die alles wieder neu zeichnet. Und genau da kommt der Fehler. Das ist die einzige Funktion die den Fehler hervorruft. Die Funktionen OHNE canvas funktionieren weiterhin, auch wenn der Fehler bei der anderen Funktion aufgetreten ist. Vielleicht doch ein Problem mit dem canvas?

viele Grüße

Stephan

Stephan 3. Okt 2002 18:15

Hi,

ja, es liegt tatsächlich an dem canvas. Ich hab es mal aus dem Code ausgeklammert und siehe da, alles funktioniert einwandfrei bis auf eben die paintbox.

Allerdings weiß ich nicht ganz was ich dagegen tun kann. Auch mit bitmap.free gehts nicht. Da erhalt ich nur eine Zugriffsverletzung.

Daniel B 3. Okt 2002 18:26

Hi,

die Box wird beim Programmstart bereit schon gezeichnet.
Sprich das OnPaint ereigniss tritt sofrt beim Start schon ein.
Ich weiss jetzt nciht wie und ob man es vorher evtl. leeren muss.
Wenn Du deine Schleife fertig hast, versuch mal ein PaintBox.Free;
Oder im OnPaint-Ereigniss.
Ich spiele grad ein bisschen damit und man kann da doch ziemliche Verletzungen bekommen.
Ich hba eben denn eindruck das da was nicht freigegeben wird, oder vorher geleert werden muss.

Grüsse, Daniel :hi:

Stephan 3. Okt 2002 18:26

Hi,

ich verwende zum zeichnen die Funktion paintox1.canvas.draw um ein Bitmap dass ich aus einer Datenbank geladen hab auf entsprechende Koordinaten die ebenfalls aus der DB kommen zu Zeichnen.

Daniel B 3. Okt 2002 18:28

Hi,

wenn Du kein Bitmap.Create hast, bruachst Du auch kein Bitmap.Free. Deswegen die Zugriffsverletzung an der Stelle.
Solltes Du allerding doch ein BM.Create irgendwo haben, gibst Du es warscheinlich an der falschen Stelle wieder Frei.

Grüsse, Daniel :hi:

Stephan 3. Okt 2002 18:38

Hi,

ich hab den Fehler, bitte nicht lachen ;)

ich hab wohl ausversehen ständig statt einer paintbox ein image verwendet. Das war nicht nur viel langsamer sondern erzeugte auch den genannten Fehler :oops:

Dennoch vielen Dank für die Hilfe!!!

Weißt du zufällig wie ich den Inhalt von einer paintbox in die andere zeichnen kann?

Daniel B 3. Okt 2002 19:50

Hi,

gleichzeitig oder nachträglich?
gleichzeitig wäre am einfachsten die gleichen Zeilen wie für die PB1 auch für die PB2 drunter zju schreiben.
Nachträglich bin ich grad am versuchen. Allerdings ohne Erfolg.

Grüsse, Daniel :hi:


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:42 Uhr.
Seite 2 von 3     12 3      

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