我遇到了一个我不明白的段错误。我正在使用 Wt 库并用信号做一些花哨的事情(我只提到它是因为它使我能够尝试调试它)。
我从一个向量中获取一个指向我的一个小部件的指针,并试图在它指向的对象上调用一个方法。Gdb 显示指针解析,如果我检查它指向的对象,它正是我需要修改的对象。在这种情况下,小部件正在向自己广播,因此它同时注册为广播者和侦听器;因此,我还能够验证“广播”指针和“侦听器”指针访问的是同一个对象。他们是这样!
但是,即使我可以看到该对象存在,并且已初始化,并且实际上是正确的对象,但当我尝试调用该对象的方法时,我会立即收到 seg 错误。我尝试了几种不同的方法(包括一些不修改对象的布尔返回)。我再次尝试通过广播器指针和侦听器指针调用它们,只是为了尝试调试。
调试器甚至不进入对象;尝试调用方法时会立即发生段错误。
代码!
/* listeners is a vector of pointers to widgets to whom the broadcasting widget
* is trying to signal.
*/
unsigned int num_listeners = listeners.size();
for (int w = 0; w < num_listeners; w++)
{
// Moldable is an abstraction of another widget type
Moldable* widget = listeners.at(w);
/* Because in this case, the broadcaster and the listener are one in the same,
* these two point to the same location in memory; this part works. I know, therefore,
* that the object has been instantiated, exists, and is happy, or we wouldn't
* have gotten to this point to begin with. I can also examine the fields with gdb
* and can verify that all of this is correct.
*/
Moldable* broadcaster_debug = broadcast->getBroadcaster();
/* setStyle is a method I created, and have tested in other instances and it
* works just fine; I've also used native Wt methods for testing this problem and
* they are also met with segfaults.
*/
widget->setStyle(new_style); // segfault goes here!
}
自从研究将指针存储在向量中并不是最好的想法以来,我已经阅读过,我应该研究 boost::shared_ptr。可能是这样,我会调查它,但它没有解释为什么在已知存在的对象上调用方法会导致段错误。我想了解为什么会这样。
感谢您的任何帮助。
编辑:我已经创建了一个详细的矢量操作要点,因为它的代码比帖子中舒适的要多。 https://gist.github.com/3111137
我没有展示创建小部件的代码,因为它是一种递归算法,为了做到这一点,我必须展示用于创建小部件的整个类决策树。可以说正在创建小部件;在浏览器中查看应用程序时,我可以在页面上看到它们。在我开始使用我喜欢的信号之前,一切都很好。
Moar 编辑:当我查看指令步进模式下的反汇编时,我可以看到就在发生段错误之前,发生了以下操作,其中第一个参数列为'void'。诚然,令我懊恼的是,我对大会一无所知,但这似乎很重要。谁能解释这条指令的含义以及它是否可能是我陷入困境的原因?
add $0x378,%rax //$0x378 is listed as 'void'
另一个编辑:根据某人的建议,我创建了一个非虚拟方法,我能够在段错误之前成功调用它,这意味着该对象实际上就在那里。如果我采用相同的方法并将其设为虚拟,则会发生段错误。那么,为什么只有虚方法会产生段错误呢?
我现在发现,如果在调用类中,我确保指定 Moldable::debug_test(和 Moldable::setStyle),则不会发生 seg 错误。但是,这似乎与 const 冒泡具有相似的效果——每个虚拟方法似乎都需要这个说明符。我以前从未见过这种行为。虽然我愿意纠正我的代码,如果它真的应该是这样的话,我不确定根本问题是否是别的。
到达那里!