2012-05-17 11 views
6

Próbuję nauczyć się gtkmm, i postanowiłem spróbować gtkmm 2.4 na razie, ponieważ wydaje się dość trudno uzyskać 3.0 działający na Debianie. W każdym razie przykład, który próbuję, jest tutaj: http://developer.gnome.org/gtkmm-tutorial/2.24/sec-helloworld.html.en. To kompiluje i działa alright aswell, ale kiedy zamknąć to valgrind donosi wiele przecieków, coś na wzór tego (po kliknięciu raz przycisk):gtkmm/C++ pierwszy przykład Witaj świecie wycieku pamięci

==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) 

to się dzieje w przypadku zatrzymania programu z Kliknij przycisk Cc lub kliknij przycisk Zamknij okno (w tym przypadku muszę użyć Shift-Meta-C, aby zamknąć okno z powodu menedżera okien). Czy jest to oczekiwane zachowanie, takie jak konektor MySQL, który nie pozwala na usunięcie tego ostatniego wskaźnika? W takim przypadku wydaje się, że wiele pamięci nie jest "dozwolone" do usunięcia? Czy po prostu brakuje mi czegoś naprawdę prostego?

Dla niego oto mój kod: (Zmieniono HelloWorld przetestować) 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; 
} 

Z góry dziękuję!

+0

Niewłaściwa odpowiedź na pytanie dotyczące gtk, ale ogólnie podczas badania wycieków pamięci użyj 'valgrind --leak-check = full --leak-resolution = high --track-origins = yes', aby uzyskać więcej szczegółów. –

+0

który daje mi zbyt dużo informacji, aby móc go przetworzyć. powinienem dodać link do wyjścia? – lfxgroove

+1

Proponuję, abyś dokładnie to przeanalizował i zrozumiał, będzie to przydatne i cenne ćwiczenie, które pomoże ci w przyszłości. Ktoś inny może to zinterpretować dla ciebie, ale jeśli to zrobi, to ty też możesz. Możesz usunąć '--leak-resolution = high', aby zmniejszyć wyjście, jeśli to pomaga. –

Odpowiedz

3

Nieszczelność nie pochodzi z kodu, ponieważ nie masz przydzielonych dynamicznie pamięci. Ponieważ zdefiniowano zmienną Test t na stosie, a nie dynamicznie, zostanie ona usunięta, gdy zniknie z zakresu. Tak będzie, gdy funkcja main() zostanie zakończona, co jest faktycznie przed zakończeniem całego programu. Klasa testowa nie ma też żadnych alokacji pamięci dynamicznej. Podając bezpośrednio mam na myśli bezpośrednio w tej klasie, ale nie w atrybutach (gtk itp.), Które zawiera.

Aby zademonstrować, że Twoja instancja Testu rzeczywiście jest usuwana, możesz umieścić printf w destruktorze. Powinieneś zobaczyć dane wyjściowe po wyjściu aplikacji.

Nawet jeśli nie określono/utworzona instancja test dynamicznie, należy dostać się do nawyku zawsze usuwając wszystko, co tworzy. W tym przypadku jest to tylko pamięć, ale mogą to być wartościowe zasoby, takie jak połączenia DB, zasoby systemu plików lub inna logika, która musi zostać wykonana przy wyjściu.

Możliwe, że Valgrind da Ci ślady na stosie miejsc, w których wydarzy się faktyczny wyciek pamięci, jestem pewien, że zobaczysz, że są one w kodzie gtk. Jeśli tak, rozważę zgłoszenie błędu. Nie byłbym zbyt zaniepokojony pamięcią still reachable (w rzeczywistości nie jest to przeciek), ale zamiast tego zajrzyj do definitely lost i indirectly lost.

+0

Czy mógłbyś wyjaśnić, dlaczego wciąż osiągalny nie jest faktycznym wyciekiem, czy wskazać mi jakieś zasoby, dlaczego tak jest? Ponadto, uruchomiłem Valgrind z --show-origin = yes i pokazuje on większość tagu gtk, ale także cairo i pango, czy mam tam również zgłaszać raporty o błędach? Z góry dziękuję! – lfxgroove

+0

@Anton, przeciek pamięci to pamięć, do której nie masz już dostępu, co oznacza, że ​​masz wskaźnik do pamięci, a następnie bez zwalniania pamięci, przypisujesz do wskaźnika inną wartość, tracąc w ten sposób jego adres. Wciąż dostępna pamięć to pamięć, do której wciąż odwołuje się wskaźnik, a program kończy się, więc pamięć nie jest "tracona". Jeśli chodzi o błędy, powiedziałabym, że tak, ale może być tak, że gtk nie zarządza poprawnie tymi bibliotekami, więc mogą je odrzucić. Kiedy zgłaszasz błędy, pokazuj stos stacków Valgrind, docenią to :) – Brady

+0

@Anton, Powinienem wspomnieć, że "Still Reachable" nie jest tak poważny jak wyciek, ale najlepiej powinien on zostać rozwiązany. – Brady

1

Ustaw zmienną środowiskową G_SLICE do rekonfiguracji alokatora pamięci GSlice.

G_SLICE=always-malloc ./your_application 

Szczegóły na temat this post.

+0

Próbowałem zarówno G_SLICE = always-malloc, jak i G_DEBUG = gc-friendly [, rezydent-moduły] to nie pomogło, ściągnęło wspomniany plik pomijając, stłumiło niektóre z błędów, które wydaje. – lfxgroove

2

Zakładając, że Gtk-- nie wycieka z pamięci, wydrukowane wyniki mogą być zgodne z tym założeniem.

Fakt, że część pamięci jest nadal dostępna przy wyjściu programu, nie jest tym samym co wyciek pamięci.

Czy następujący program powoduje wyciek pamięci?

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

Może się tak wydawać, ale pełna odpowiedź powinna brzmieć: To zależy!

Jeśli nie używamy MS/DOS i "a" jest potrzebne do samego końca programu, może to być trudno zdefiniowane wyciek ... możemy powiedzieć, że programista pozostawił odpowiedzialność za oczyszczenie do system operacyjny.

Ponadto Valgrind jest bardzo dobrym i przydatnym narzędziem, ale może zgłaszać fałszywe alarmy.

+0

Więc mówisz, że nie mogą/nie posprzątają ostatnich części pamięci i pozostawiają to osowi? Czy istnieje jakaś dokumentacja na ten temat? Czy to normalne? – lfxgroove

+0

Robiłem ogólną uwagę, nie mogę mówić za programistów gtkmm. Uważam, że właściwym miejscem do spytania o to, co zamierzają zrobić, jest ich lista mailingowa. – baol

Powiązane problemy