2012-05-17 8 views
6

私はgtkmmを学ぼうとしていて、gtkmm 2.4をDebian上で動作させるのはかなり難しいようですので、当面は試してみることにしました。とにかく、私が試している例はここにあるものです:http://developer.gnome.org/gtkmm-tutorial/2.24/sec-helloworld.html.en。それは罰金コンパイルし、それは大丈夫aswellを実行しますが、私は閉じたときには、Valgrindのリークの多くを報告し、(一回ボタンをクリックした後)この線に沿って何か:gtkmm/C++最初のこんにちはワールドリーディングメモリ

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

私はプログラムを停止した場合、この問題が発生しましたCcをクリックするか、閉じるウィンドウボタンをクリックしてください(この場合、ウィンドウマネージャーのためにShift-Meta-Cを使用してウィンドウを閉じる必要があります)。これは、MySQLのコネクタのように予想される動作ですが、最後の1つのポインタを削除することはできませんか?その場合、「許可されていない」メモリが大量に削除されているようです。それとも、本当にシンプルなものが欠けていますか?それを期すため

は、ここに私のコードです:(テストへの変更のHelloWorld) 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; 
} 

ありがとうございます!

+0

あなたのgtk質問には適切な答えではありませんが、一般的にはメモリリークを調べる際に、詳細を知るために 'valgrind --leak-check = full --leak-resolution = high -track-origins = yes'を使用してください。 –

+0

それは私にそれを処理するにはあまりにも多くの情報を与えます。出力へのリンクを追加する必要がありますか? – lfxgroove

+1

私はあなたがそれを慎重に調べて理解することをお勧めします、それは将来役立つ役に立つ貴重な運動です。誰かがあなたのためにそれを解釈することができますが、もしあなたがそれを行うことができればあなたもできます。もし--leak-resolution = highを削除すると出力を減らすことができます。 –

答えて

3

ダイナミックメモリ割り当てがないと考えると、リークはあなたのコードからではありません。 Test t変数は動的にスタックに定義されていないため、範囲外になると削除されます。これはmain()関数が完了するときです。実際はプログラム全体が完了する前です。また、Testクラスにはダイレクトダイナミックメモリ割り当てがありません。直接言及することによって、私はそのクラスに直接的に意味しますが、属性(gtkなど)には含まれません。

Testインスタンスが実際に削除されていることを示すために、destructorにprintfを置くことができます。アプリケーションが終了すると、出力が表示されます。あなたが/動的テストインスタンスを作成して定義されていた場合であっても

、あなたが作成するすべてのものを削除常にの習慣を身に取得する必要があります。この場合、メモリだけですが、DB接続、ファイルシステムリソース、または終了時に実行する必要がある他のロジックなど、より貴重なリソースになる可能性があります。

Valgrindは、実際にメモリリークが発生する場所をスタックトレースできるので、gtkコード内にあることが分かります。もしそうなら、私はバグを提起することを検討するだろう。私はstill reachableメモリ(実際にはリークではない)について気にする必要はありませんが、代わりにdefinitely lostindirectly lostを参照してください。

+0

あなたはなぜまだ到達可能であるのかを実際のリークでないと説明してください、それはなぜですか?また、私はValgrindを--show-origin = yesで走らせました。そしてgtkだけでなくカイロとパンゴの大部分を表示しています。前もって感謝します! – lfxgroove

+0

@Anton、メモリリークはあなたがもはやアクセス権を持たないメモリです。メモリへのポインタがあれば、メモリを解放せずにポインタに別の値を代入してアドレスを失います。まだ到達可能なメモリは、ポインタによってまだ参照されているメモリであり、プログラムは終了するので、メモリは "失われていません"。バグについては、はいと言いますが、gtkがこれらのライブラリを正しく管理していない可能性がありますので、拒否する可能性があります。バグを報告するとき、Valgrindのスタックトレースを表示すると、彼らはそれを感謝します:) – Brady

+0

@Anton、 "Still Reachable"はリークほど深刻ではありませんが、理想的には対処すべきです。 – Brady

1

GSliceメモリアロケータを再設定するには、G_SLICE環境変数を設定します。

G_SLICE=always-malloc ./your_application 

詳細については、this postを参照してください。

+0

私は、G_SLICE = always-mallocとG_DEBUG = gc-friendly [、residident-modules]の両方を試してみました。 – lfxgroove

2

Gtk--メモリがリークしないと仮定すると、投稿した出力はこの前提条件と互換性があります。

プログラム終了時にまだメモリに到達可能であるという事実は、メモリリークと同じではありません。

次のプログラムがメモリをリークしますか?

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

完全に回答する必要があります:それは依存する必要があります。

MS/DOSを使用しておらず、プログラムの最後まで "a"が必要な場合、これはほとんど漏れを定義することはできません...プログラマーは、基礎となるオペレーティングシステム。

さらに、Valgrindは非常に優れた有用なツールですが、偽陽性を報告することができます。

+0

あなたが言っていることは、彼らは最後の記憶を取り除くことはできませんし、それを根底にあるosに残すことができないということですか?これに関する文書がありますか?また、それはいつもですか? – lfxgroove

+0

私は一般的な発言をしていましたが、私はgtkmm開発者のために話すことができません。彼らの意図したことを聞く正しい場所はメーリングリストだと私は思う。 – baol

関連する問題