【问题标题】:C++: this-pointer overwrittenC++:这个指针被覆盖
【发布时间】:2026-01-29 01:35:01
【问题描述】:

请查看我的源文件,它们有点太长了,无法在此处发布:

X11Painter.cpp: @987654321@

X11Painter.h: @987654322@

这个类的行为在我看来很奇怪

我有以下测试用例:

#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 出现段错误的原因时,我发现 show() 中的大多数变量都被覆盖并且与构造函数中的完全不同。

我输入int some_test 看看发生了什么。为什么值会发生变化?

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

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

有人知道为什么会发生这种奇怪的事情吗? 我知道堆栈上的变量会发生什么,但我们仍然在 main 那里......

可能与 X11 库有关吗?

【问题讨论】:

  • 您应该使您的源文件足够小,以便在此处发布。这有两个好处:第一,更多的人会看到它们;其次,在缩小它们的过程中,您可能会自己找到问题的根源。

标签: c++ pointers segmentation-fault x11


【解决方案1】:

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

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

这并没有像你想象的那样做,因为在 C++ 中没有构造函数链接。上面的代码所做的是构造一个临时的X11Painter 对象,为该临时对象调用另一个构造函数,但实际上并未初始化您要构造的对象中的任何内容。

要解决此问题但保留相同的行为,请删除您的无参数构造函数并在您的 .h 文件中将另一个构造函数声明为

X11Painter(int screenno = -1);

如果您不提供 screenno 参数,这将默认为 -1

【讨论】:

  • +1 用于指出错误,但要注意两点: 1. 在下一个 C++ 版本中,将有构造函数链接,尽管语法不同。 2. 构造函数应该声明为explicit,因为从intX11Painter 的隐式转换是没有意义的。
  • Philipp:你说的第二句话到底是什么意思?从 int 到 X11Painter 的转换在哪里?谢谢
  • @Atmocreations:如果你有一个单参数构造函数,就像在这种情况下,它允许从参数类型到对象类型的隐式转换。这意味着您可以使用int,其中需要X11Painter,并且将调用构造函数进行转换。声明构造函数explicit 可以防止这种隐式类型转换。
  • @Philipp:在阅读了一些文档之后,我终于明白了你的想法。确实需要注意的事情。谢谢!
  • @jk [接受]:很好的答案。谢谢!按照建议进行了尝试,并且有效。学到了另一件重要的事情,关于如何在脚上射击自己:P
【解决方案2】:

这在我看来就像堆栈损坏,很可能是由

        Window                  window;
        XSetWindowAttributes    winattr;

成员,因为其他都是原始类型。例如,我注意到了这一点:

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

如果窗口和显示器没有正确的内存量,这可能会发生故障。 但是,如果不了解 X11 库,我就帮不上什么忙了。

【讨论】:

  • 这实际上是正确的。这些功能旨在以这种方式使用。 Window 最终是一个无符号长整数,而 Display 是一个结构。但是感谢您指出这一点。