Delphi-PRAXiS

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 2. Okt 2002 10:10


Für diesen Vorgang ist nicht genügend Speicher verfügbar
 
Hallo,

ich hab ein Datenbankprogramm geschrieben was zur Zeit 3 TTable und 2 TQuery beinhaltet. (4 von denen sind in der Regel immer aktiv). Ich benutze die Standardkomponenten von Delphi 6 prof. unter der Lasche BDE. Ich spreche eine Paradox Tabelle direkt über die BDE an. Soweit funktioniert schonmal alles gut. Sobald ich allerdings ein weiteres Form öffne (editor.visible := true) und dann nochmal die Funktion aufrufe die mir in einer Schleife Daten aus der Datenbank holt und auf einen Canvas zeichnet kommt nur folgende Fehlermeldung:

" Für diesen Vorgang ist nicht genügend Speicher verfügbar "

wüsstet Ihr wie ich diesen Fehler umgehen kann? Ich hab schon alles versucht und komm nicht drauf. Über Hilfe wäre ich dankbar.

viele Grüße

Stephan

Boxma 2. Okt 2002 10:40

Benutzt du nur die selben Tables und Querys?
Sonst kann es auch sein das ein JOIN in einer Abfrage
unmengen an Daten liefert, damit hatte ich vor einiger Zeit auch mal diese Fehlermeldung bekommen. :witch:

Christian Seehase 2. Okt 2002 10:43

Moin Stephan,

kommt der Fehler sofort, oder erst nachdem einige Daten verarbeitet wurden?

Für mich klingt das so, als wären irgendwelche Resourcen am Ende (z.B. Handle), als würdest Du immer eine Datei in der Schleife öffnen, aber nicht wieder schliessen.

Auf welchem Betriebbsystem tritt dieser Fehler auf?

Lemmy 2. Okt 2002 10:53

Hi,

der Fehler liegt nicht an übermäßigem Ressourcenverbrauch sondern definitiv an der BDE. Ich glaube mich zu erinnern, dass das beim Gebrauch von TQuerys auftritt. Eine Behebung, Workaround kenne ich im Moment nicht. Evtl. findest Du hier was:
http://codecentral.borland.com/codec...odid=6&catid=3

Grüße
Lemmy

Boxma 2. Okt 2002 11:16

Der Fehler hat nicht nur mit dem Query zu tun, kann genausogut in einer StoredProcedure auftreten. Deshalb wäre die Antwort auf Christians frage ob der Fehler sofort oder erst nach einiger Rechenzeit auftritt interessant. Genausogut kann es nichts damit zu tun haben wie Christian meint.
:witch:

Stephan 2. Okt 2002 11:36

Hallo,

der Fehler tritt in diesem Fall bei der TTable Kompeonente auf. Sie liest (zur Zeit nur 2 Datensätze) in ein StringGrid ein. Danach werden die Datensätze von oben nach unten bearbeitet und die Bilder aus der Datenbank auf die entsprechenden Koordinaten in einem canvas gezeichnet. Soweit funktioniert das ganz gut. Im Hauptformular tritt am Anfang auch kein Fehler auf. Ich benutze mehrere Formulare in denen ich die unit2 (das DataModule wo sich die TTable und TQuery befinden) über uses einbind. Soweit so gut. Ich öffne ein Formular (der Editor) der wenn man auf refresh klickt die oben genannte Procedure in form1 ausführt. Aber dabei erscheint sofort diese Fehlermeldung. Wenn ich das Form schließe kann ich selbst auch nicht mehr auf dem form1 die funktion aufrufen da der fehler ebenfalls sofort erscheint. ich muss das Programm neu starten.

Ich benutz windows 2000 prof.

viele Grüße

Stephan

Christian Seehase 2. Okt 2002 12:29

Moin Stephan,

werden die Unterformulare oder irgendwelche Objekte darin dynamisch erzeugt?

Irgendwo hier im Forum gibt es, glaube ich, auch einen Link auf memproof. Damit lassen sich eventuell vorhandene Speicherlöcher entdecken.

Stephan 2. Okt 2002 12:47

Hallo,

nein, die Formulare werden nicht dynamisch erzeugt :?

viele Grüße

Stephan Munz

Stephan 3. Okt 2002 17:02

Hi,

hm, ich hab nichts zu memproof gefunden ;(

viele Grüße

Stephan

Daniel B 3. Okt 2002 17:12

Hi Stephan,

und Du gibst auch alles wieder Free;?

Grüsse, Daniel :hi:

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:

d3g 3. Okt 2002 19:50

Hi Stephan,

ich glaube, es würde helfen, wenn du den Code der entsprechenden Stelle posten würdest. So, wie du es sagst, kann ich mir irgendwie nicht vostellen, was du da genau machst und was du wo freigibst...

MfG,
d3g

Daniel B 3. Okt 2002 19:51

Hi d3g,

Das hat sich doch schon erledigt.
Er hat ein Image statt einer PaintBox gehabt.

Grüsse, Daniel :hi:

Christian Seehase 4. Okt 2002 01:16

Moin Stephan,

wenn Du bei Bitmap.Free eine Zugriffsverletzung erhältst kann man davon ausgehen, dass das Objekt (Bitmap) nicht mehr existiert.

Also ich glaube ohne ein klein wenig Sourcecode ist jetzt wohl kaum weiterzukommen.

Stephan 4. Okt 2002 08:41

Hi,

Danke für die Antwort. Jedoch hat sich das Problem bereits erledigt. Was genau der Fehler war kannst du paar Posts weiter oben lesen ;)


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