2010-12-11 5 views
2

を上書き私のソースファイルを見てください、彼らはここに投稿するビット長すぎます:C++:このポインタは

X11Painter.cpp: http://pastebin.com/gu4SrHUr

X11Painter.h: http://pastebin.com/3ktp1Fvn

このクラスの振る舞いがあります私の意見では非常に奇妙な

私がいる、次のテストケース:

#include "X11Painter.h" 
int main() 
{ 
    X11Painter p ; 
    p.show(); 
} 

ライン

g++ -O0 -g -o test2 test2.cpp X11Painter.cpp -lX11 -lXfixes -lXinerama 

でそれをコンパイルし、単にそれは次のようん実行している:私は

this->some_test=1234 
this->screen:0 
1:: this->display='0x8b73008'; this->window='77594625' 
width: 3200 
0xbff91bdc 
this->some_test=1234 
this->some_test=3682292 
Segmentation fault 

よX11のウィンドウをマップしようとしていますX11Painter::show()

X11Painter.cpp:83がsegfaultingである理由を調査し始めたとき、コンストラクタ内にあるよりも多くの変数が上書きされ、完全に異なっていることが分かりました。

私はint some_testに何が起こっているか見てみましょう。なぜ値が変わるのですか?

printf("%p\n", this)を実行すると、ポインタも変更されます。私はどこかで、このポインタが上書きされていると思う。しかし、なぜこれは起こっているのですか? dddを使ったデバッグでは、this-> some_valueがコンストラクタを終了している間に修正されています。

テストクラス(パブリックコンストラクタ、パブリックメソッドとプライベート変数を持つクラス)を使って簡単なテストを行うと問題なく動作します。

この奇妙なことが起こっている理由は誰にも分かりますか? 私はスタック上にある変数に何が起こっているのか知っていますが、まだメインにあります。

X11-ライブラリに関連するかもしれませんか?

+0

ソースファイルをここに投稿するのに十分小さくする必要があります。これには2つの利点があります:第1に、より多くの人々がそれらを見るでしょう。第二に、それらを小さくする過程で、あなた自身が問題の原因を見つけるかもしれません。 – TonyK

答えて

12

C++には、コンストラクタ連鎖が存在しないので、あなたはこの

X11Painter::X11Painter() 
{ 
    X11Painter(-1); 
} 

これは、あなたがそれをやっていると思う何をしていませんありません。上のコードが実行しているのは、一時的なX11Painterオブジェクトを構築し、その一時オブジェクトの別のコンストラクタを呼び出して、実際に構築したいオブジェクトの何かを初期化しないことです。

は、この問題を解決するが、同じ動作を維持する、あなたのパラメータなしのコンストラクタを削除し、あなたの .hファイルで使用すると、1つを指定しない場合 -1screenno引数をデフォルトになります

X11Painter(int screenno = -1); 

このように、他のコンストラクタを宣言します。

+4

+1はエラーを指摘するが、2つの注意点がある。1.次のC++バージョンでは、構文が異なるにもかかわらず、コンストラクターチェーニングが行われる。 2. 'int'から' X11Painter'への暗黙の変換が意味を持たないので、コンストラクタは '明示的に'宣言されるべきです。 – Philipp

+0

Philipp:第二の発言ではどういう意味ですか? intからX11Painterへの変換はどこですか?ありがとう – Atmocreations

+1

@Atmocreations:この場合のように1パラメータのコンストラクタがある場合、パラメータ型からオブジェクト型への暗黙的な変換が可能です。ここでは 'X11Painter'が期待され、変換を行うためにコンストラクタが呼び出されるところで' int'を使うことができることを意味します。コンストラクタ 'explicit'を宣言することで、この暗黙的な型変換が防止されます。 – JaakkoK

1

他はすべてのプリミティブ型であるので、これは、最も可能性の高い

 Window     window; 
     XSetWindowAttributes winattr; 

部材を介して発生する、スタックの破損のように私には見えます。たとえば、私はこれに気づいた:

XStoreName(this->display, this->window, "LaserFinger"); 

ウィンドウとディスプレイに正しい量のメモリがない場合、これはkaboomになる可能性があります。 しかし、X11ライブラリを知らなくても、私ははるかに役立つことはできません。お使いのパラメータなしのコンストラクタで

+0

これは実際には正しいです。これらの関数はそのように使用することを意図しています。ウィンドウは最後に符号なしlongであり、Displayは構造体です。しかし、それを指摘してくれてありがとう。 – Atmocreations