2010-12-11 100 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时,我发现大部分变量都被覆盖,并且在show()中完全不同于构造函数中的变量。

我把int some_test看看发生了什么。为什么地狱是价值的变化?

如果我做printf("%p\n", this),指针也会改变。我怀疑在某个地方,这个指针被覆盖。但为什么会发生?用ddd调试告诉我,this-> some_value在退出构造函数时被正确修改。

使用testclass(具有公共构造函数的类,一个公共构造函数和一个私有变量)进行简短测试并没有任何问题。

有没有人知道为什么会发生这种奇怪的事情? 我知道堆栈上的变量会发生什么变化,但我们仍然处于主要变量的状态......

可能与X11库有关吗?

+0

你应该使你的源文件小到足以在这里发布。这有两个好处:首先,更多的人会看到他们;其次,在缩小它的过程中,你可能会自己找到问题的根源。 – TonyK 2010-12-11 14:06:41

回答

12

在你的参数的构造函数,你这样做

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

这不是做你觉得它在做什么,因为在C中没有构造函数链++。上面的代码正在构造一个临时对象,调用该临时对象的另一个构造函数,但实际上并未初始化要构建的对象中的任何对象。

为了解决这个问题,但保留相同的行为,删除您的参数的构造函数并在.h文件中声明的其它构造函数

X11Painter(int screenno = -1); 

这将默认screenno参数-1如果你不提供一个。

+4

+1用于指出错误,但有两点注意:1.在接下来的C++版本中,将存在构造函数链,尽管语法不同。 2.构造函数应该声明为'explicit',因为从'int'到'X11Painter'的隐式转换没有任何意义。 – Philipp 2010-12-11 14:10:48

+0

Philipp:你对第二句话意味着什么?从int到X11Painter的转换在哪里?谢谢 – Atmocreations 2010-12-11 14:13:40

+1

@提示:如果你有一个单参数构造函数,就像在这种情况下一样,它允许从参数类型到对象类型的隐式转换。这意味着你可以在'X11Painter'的地方使用'int',并且调用构造函数来完成转换。声明构造函数'explicit'可以防止这种隐式类型转换。 – JaakkoK 2010-12-11 14:16:35

1

这在我看来就像堆栈损坏,通过

 Window     window; 
     XSetWindowAttributes winattr; 

成员最有可能出现的,因为其他人都基本类型。例如,我注意到了这一点:

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

如果窗口显示没有正确的内存量,这可以去KABOOM。然而,如果不知道X11库,我不能提供更多的帮助。

+0

这实际上是正确的。这些功能旨在以这种方式使用。窗口最后是一个无符号long,Display是一个结构体。但谢谢你指出。 – Atmocreations 2010-12-11 14:16:57