2012-05-17 9 views
6

Ich versuche gtkmm zu lernen, und entschied mich, gtkmm 2.4 vorläufig zu versuchen, da es ziemlich schwierig zu sein scheint, 3.0 an Debian zu arbeiten. Wie auch immer, das Beispiel, das ich versuche, ist das hier: http://developer.gnome.org/gtkmm-tutorial/2.24/sec-helloworld.html.en. Es kompiliert fein und es läuft gut als gut, aber wenn ich es schließen, berichtet valgrind viele Lecks, etwas entlang der Linien von diesem (nach dem Knopf einmal klicken):gtkmm/C++ erste Hallo Welt Beispiel undichten Speicher

==4254== Memcheck, a memory error detector 
==4254== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. 
==4254== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info 
==4254== Command: ./bin/jmb 
==4254== 
Hello World 
==4254== 
==4254== HEAP SUMMARY: 
==4254==  in use at exit: 942,940 bytes in 7,968 blocks 
==4254== total heap usage: 14,191 allocs, 6,223 frees, 3,272,961 bytes allocated 
==4254== 
==4254== LEAK SUMMARY: 
==4254== definitely lost: 2,620 bytes in 6 blocks 
==4254== indirectly lost: 5,936 bytes in 187 blocks 
==4254==  possibly lost: 358,625 bytes in 1,775 blocks 
==4254== still reachable: 575,759 bytes in 6,000 blocks 
==4254==   suppressed: 0 bytes in 0 blocks 
==4254== Rerun with --leak-check=full to see details of leaked memory 
==4254== 
==4254== For counts of detected and suppressed errors, rerun with: -v 
==4254== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 9 from 9) 

Dies geschieht, wenn ich das Programm beenden mit Cc oder klicken Sie auf die Schaltfläche zum Schließen des Fensters (in diesem Fall muss ich Shift-Meta-C verwenden, um das Fenster wegen des Fenstermanagers zu schließen). Ist dies das erwartete Verhalten wie der Connector von MySQL, der es Ihnen nicht erlaubt, diesen letzten Zeiger zu löschen? In diesem Fall scheint es, als würde viel Speicher nicht "gelöscht" werden können? Oder fehlt mir gerade etwas wirklich Einfaches?

Aus Gründen der hier ist mein Code: (geändert Hello World zu Test) main.cpp:

#include "gui/Test.hpp" 
#include <gtkmm/main.h> 
int main(int argc, char **argv) 
{ 
    Gtk::Main kit(argc, argv); 
    Test t; 
    Gtk::Main::run(t); 
    return 0; 
} 

Test.hpp:

#pragma once 

#include <gtkmm/button.h> 
#include <gtkmm/window.h> 

class Test 
    : public Gtk::Window 
{ 
public: 
    Test(); 
    virtual ~Test(); 

protected: 
    //Signal handlers: 
    void on_button_clicked(); 

    //Member widgets: 
    Gtk::Button m_button; 
}; 

Test.cpp:

#include "Test.hpp" 
#include <iostream> 

Test::Test() 
    : m_button("Hello World") // creates a new button with label "Hello World". 
{ 
    // Sets the border width of the window. 
    set_border_width(10); 

    // When the button receives the "clicked" signal, it will call the 
    // on_button_clicked() method defined below. 
    m_button.signal_clicked().connect(sigc::mem_fun(*this, 
       &Test::on_button_clicked)); 

    // This packs the button into the Window (a container). 
    add(m_button); 

    // The final step is to display this newly created widget... 
    m_button.show(); 
} 

Test::~Test() 
{ 

} 

void Test::on_button_clicked() 
{ 
    std::cout << "Hello World" << std::endl; 
} 

Vielen Dank im Voraus!

+0

Keine richtige Antwort auf Ihre GTK Frage, aber im Allgemeinen bei der Untersuchung von Speicherlecks verwenden Sie 'valgrind --leak-check = full --leak-Auflösung = high --track-origins = yes ', um mehr Details zu erhalten. –

+0

das gibt mir zu viele Infos um es verarbeiten zu können. sollte ich einen Link zur Ausgabe hinzufügen? – lfxgroove

+1

Ich schlage vor, Sie untersuchen es sorgfältig und verstehen es, es wird nützlich sein und eine wertvolle Übung, die Ihnen in Zukunft helfen wird. Jemand anders könnte es für dich interpretieren, aber wenn sie es können, dann kannst du es auch. Sie können '--leak-resolution = high 'entfernen, um die Ausgabe zu reduzieren, wenn das hilft. –

Antwort

3

Das Leck stammt nicht von Ihrem Code, da Sie keine dynamischen Speicherzuweisungen haben. Da Sie Ihre Test t Variable auf dem Stapel und nicht dynamisch definiert haben, wird sie gelöscht, wenn sie den Gültigkeitsbereich verlässt. Das wäre, wenn die main() -Funktion abgeschlossen ist, was tatsächlich vor dem Abschluss des gesamten Programms ist. Noch hat die Testklasse direkte dynamische Speicherzuordnungen. Mit direkter Erwähnung meine ich direkt in dieser Klasse, aber nicht in den Attributen (gtk, etc) die es enthält.

Um zu demonstrieren, dass Ihre Test-Instanz tatsächlich gelöscht wird, können Sie printf in den Destruktor einfügen. Sie sollten die Ausgabe sehen, wenn die Anwendung beendet wird.

Auch wenn Sie definiert hatten/dynamisch die Test-Instanz erstellt, sollten Sie es sich zur Gewohnheit immer Löschen bekommen alles, was Sie erstellen. In diesem Fall ist es nur Speicher, aber es könnte wertvollere Ressourcen wie DB-Verbindungen, Dateisystemressourcen oder eine andere Logik sein, die beim Beenden ausgeführt werden muss.

Es ist möglich für Valgrind, Ihnen Stack-Spuren zu geben, wo die tatsächlichen Speicherlecks passieren, ich bin ziemlich sicher, dass Sie sehen werden, dass sie im gtk-Code sind. Wenn ja, würde ich in Erwägung ziehen, einen Fehler zu melden. Ich wäre nicht zu besorgt über die still reachable Speicher (es ist nicht wirklich ein Leck), sondern schauen Sie in die definitely lost und indirectly lost.

+0

Könnten Sie bitte erklären, warum immer noch erreichbar ist kein echtes Leck oder weisen Sie mich auf einige Ressourcen, warum das ist? Außerdem habe ich Valgrind mit --show-origin = yes laufen lassen und es zeigt die meisten gtk aber auch cairo und pango, sollte ich auch dort Fehlerberichte einreichen? Danke im Voraus! – lfxgroove

+0

@Anton, ein Speicherleck ist Speicher, auf den Sie keinen Zugriff mehr haben, dh Sie hatten einen Zeiger auf den Speicher, dann geben Sie dem Speicher einen anderen Wert und verlieren somit seine Adresse, ohne den Speicher freizugeben. Immer noch erreichbarer Speicher ist Speicher, der immer noch von einem Zeiger referenziert wird, und das Programm endet, so dass der Speicher nicht "verloren" ist. Was die Fehler betrifft, würde ich ja sagen, aber es kann sein, dass gtk diese Bibliotheken nicht korrekt verwaltet, so dass sie es möglicherweise ablehnen. Wenn Sie die Fehler ablegen, zeigen Sie die Valgrind Stacktrace, sie werden es zu schätzen :) – Brady

+0

@Anton, ich sollte erwähnen, dass "immer noch erreichbar" ist nicht so ernst wie ein Leck, aber im Idealfall sollte es noch adressiert werden. – Brady

1

Legen Sie die G_SLICE-Umgebungsvariable fest, um den GSlice-Speicherzuordner neu zu konfigurieren.

G_SLICE=always-malloc ./your_application 

Weitere Informationen finden Sie unter this post.

+0

Ich habe versucht sowohl G_SLICE = immer-malloc und G_DEBUG = gc-freundlich [, resident-modules] es hat nicht viel geholfen, heruntergeladen die erwähnte Unterdrückungsdatei, es unterdrückt einige der Fehler scheint es. – lfxgroove

2

Angenommen, Gtk-- verliert keinen Speicher, die von Ihnen gepostete Ausgabe kann mit dieser Annahme kompatibel sein.

Die Tatsache, dass einige Speicher beim Programm-Exit noch erreichbar sind, ist nicht dasselbe wie ein Speicherleck.

Führt das folgende Programm Speicherverlust aus?

int main() { 
    int* a = new int[10]; 
    return 0; 
} 

Es mag so scheinen, aber die vollständige Antwort sollte sein: Es kommt darauf an!

Wenn wir nicht MS/DOS verwenden und "a" bis zum Ende des Programms benötigt wird, kann dies kaum als ein Leck definiert werden ... wir können sagen, dass der Programmierer die Verantwortung für die Säuberung der zugrunde liegendes Betriebssystem.

Darüber hinaus Valgrind ist ein sehr gutes und nützliches Werkzeug, aber kann False Positives melden.

+0

Also was du sagst ist, dass sie nicht die letzten Teile des Gedächtnisses bereinigen können und das dem zugrunde liegenden Betriebssystem überlassen? Gibt es dazu eine Dokumentation? Ist das auch normal? – lfxgroove

+0

Ich machte eine allgemeine Bemerkung, ich kann nicht für die Entwickler von gtkmm sprechen. Ich denke, der richtige Ort, um zu fragen, was sie tun wollten, ist ihre Mailingliste. – baol