memory leak

Plattformunabhängige GUIs mit wxWidgets.
Antworten
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

Hallo

Ich habs gerade geschafft, folgenden Fehler (reproduzierbar) zu erhalten.
Kann mir jemand sagen, ob ich da schuld dran bin oder wx selbst? :?:
swig/python detected a memory leak of type 'wxPyTreeCtrl *', no destructor found.
Traceback (most recent call last):
File "wx_gui.py", line 366, in OnImport
self.panel.tree.__init__(self.panel1)
File "wx_gui.py", line 229, in __init__
wx.TreeCtrl.__init__(self, parent, -1, style=style)
File "/usr/lib/python2.5/site-packages/wx-2.8-gtk2-unicode/wx/_controls.py", line 5177, in __init__
self._setOORInfo(self);TreeCtrl._setCallbackInfo(self, self, TreeCtrl)
File "/usr/lib/python2.5/site-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 3772, in _setOORInfo
args[0].this.own(False)
File "/usr/lib/python2.5/site-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 13772, in __getattr__
raise PyDeadObjectError(self.attrStr % self._name)
wx._core.PyDeadObjectError: The C++ part of the CategoriesList object has been deleted, attribute access no longer allowed.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Bin mir nicht sicher, ob dazu irgendjemand irgendetwas sagen kann, wenn Du uns nicht verrätst, wie denn dieser Fehler überhaupt provoziert wurde.

Allerdings klingt die Fehlermeldung schon etwas seltsam. Will ich wohl zugeben ...

Gruß,
Christian
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

Ja ich weiß..aber ich kann nicht wirklich meinen ganzen Code posten und ich habs bis jetzt nicht geschafft, das zusammenzukürzen und den Fehler zu behalten. Ich probiers später nochmal und meld mich dann.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Eindampfen sowieso und ggf. auch http://paste.pocoo.org/

Gruß,
Christian
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

Tja, also da ist was faul.

(Auch hier ausgelagert)

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wxversion
wxversion.ensureMinimal("2.7.1")
import wx


class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1)
        self.label = wx.StaticText(self, -1, "Hello World")
        self.CrashMe()

    def CrashMe(self):
        self.label.__init__(self, -1, "Oh no")


app = wx.PySimpleApp()
frame = MyFrame()
frame.Show()
app.MainLoop()
Ergibt den bekannten Fehler.

Interessant ist, dass das nicht nur mit wx.TreeCtrl funktioniert, sondern auch mit anderen (hier z.B. wx.StaticText).

Der Fehler tritt bei mir unter Linux/Gtk mit der 2.6er (ich hab 2.6.3.2) nicht auf, nur bei der 2.8er (2.8.1.1).

Mach ich hier was falsch oder bin ich über einen Bug gestolpert? :roll:
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo alan!

In Zeile 13 wird dein Label initialisiert. Einmal! Mehr ist nicht! -- Du kannst/darfst es nicht noch einmal initialisieren. Es gibt auch keinen Grund dafür.

Falls du in deinem Code so etwas öfter machst --> FEHLER!!! Sofort ausbessern. Dann stimmt etwas nicht.

Wenn du nur den Text ändern möchtest:

Code: Alles auswählen

self.label.SetLabel("Oh yes")
self.label.Refresh()
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Ahaaaa!
Was möchtest Du denn eigentlich erreichen? Die __init__-Methode eines Widgets aufrufen, nachdem es längst erzeugt und plaziert wurde. Das ist generell keine gute Idee. In dem Zusammenhang ist die Fehlermeldung absolut sinnvoll.

Was willst Du denn eigentlich *wirklich* erreichen? Einen statischen Text läßt man eigentlich unangetastet. Man schließt oder ersetzt oder verändert allenfalls das Widget in dem er vorkommt (oder verändert den Text an sich ...)

Die __init__-Methode einer TreeCtrl kannst Du beispielsweise in einem Panel aufrufen:

Code: Alles auswählen

wx.TreeCtrl.__init__(self, parent, ...)
aber wenn Du das Ctrl zuweist:

Code: Alles auswählen

self.tree = MyTreeCtrl(self, ....)
kannst Du anschließend keine __init__ von self.tree aufrufen.

Gruß,
Christian
Zuletzt geändert von CM am Montag 8. Oktober 2007, 17:20, insgesamt 1-mal geändert.
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

Hmm eigentlich habe ich das bei meinem TreeCtrl gemacht, nachdem neuen Daten zum Darstellen waren. Den entsprechenden Code kann ich natürlich von __init__ in eine andere Methode schieben.

Aber wieso produziert das erst in der 2.8-Version einen Fehler?
BlackJack

Ich würde sagen Du machst was falsch. Das man einfach so die `__init__()` erneut aufrufen kann und danach einen definierten Zustand des Objekts hat, ist jedenfalls nicht garantiert. Selbst in reinem Python-Code nicht.

In der `__init__()` wird wahrscheinlich im C++-Teil ein "echtes" wxStaticText-Widget neu erzeugt. Und wenn Du das noch einmal aufrufst, dann wird vielleicht wieder ein neues erzeugt, ohne das alte zu zerstören.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

alan hat geschrieben:Aber wieso produziert das erst in der 2.8-Version einen Fehler?
Weil zwischenzeitlich am API rumgefummelt wurde. Das stellt aber eine Verbesserung dar, weil es Dich (uns) solche Fehler nicht mehr machen läßt.

Gruß,
Christian
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Außerdem: Der Traceback hat *nichts* mit einem Memory Leak zu tun. Wäre vielleicht gut in Zukunft Threads ein bißchen aussagekräftiger zu bennenen. ;-)
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

Aha jetzt bin ich schlauer :) Danke.

Wegen dem Titel: Ich konnte mit dem Fehler nicht wirklich was anfangen und ein Google-Treffer hat irgendwas von GC+memory leak gefaselt. No pun intended :-)
Antworten