这个问题以类似的方式被多次提出,例如在stackoverflow或forum.qt.io或qtcentre.org。问题是此错误消息非常模糊,以至于一个解决方案无法应用于另一个方案。大多数线程在讨论过程中死了但是:-(
因此,我在Qt应用程序中获得的完整错误消息是:
找不到“OneOfMyClasses”的虚拟表的链接器符号 值找到“QString :: shared_null”而不是
OneOfMyClasses根据各种变化而变化,QString :: shared_null对于我得到的所有错误都保持不变。以下是我的日志记录控制台的屏幕截图:
它发生的位置是在当前位置之前的源行中的此函数(黄色箭头):
所以根据消息,我走进m_pStateWidget->insertNavLabel(...)
,错误信息打印在Qt内部与QString类相关的构造函数中。所以我尝试了以下方法,将问题从这个代码位置移开:
执行此操作时,我在消息中的另一个类名称下面会显示相同的错误消息,请注意QString :: shared_null保持不变。
在我看来,我有一些腐败的记忆。
感谢您的任何提示或帮助! :-)
编辑:现在变得非常有趣。我在消息打印之前就已经进入了每一个函数,最后我得到了以下错误消息:
在这个位置:
当我在QtCreator中浏览调用堆栈时,每次在堆栈中选择另一个函数时,都会反复打印错误。
原因:在代码中的某处,您可能会超出实际内存
例1:
int elmArray[10];
for(int i = 0; i < 20; ++i)
{
elmArray[i] = 0;
}
在上面的例子中,实际的数组大小是10,但我们将索引的值分配给10以上。
例2:
char* cpyString;
strcpy(cpyString , "TEST");
这些场景可能最终将值写入其他对象。大多数可能会破坏虚拟表。这给出了上述警告。
修复:如您所知,只需更正下面的代码即可。示例:
int elmArray[10];
for(int i = 0; i < 10; ++i)
{
elmArray[i] = 0;
}
char cpyString[10];
strcpy(cpyString , "TEST");
在你的情况下似乎是,你将QTString :: shared_null分配给一些未初始化的字符串。
在不同的网站上有各种各样的线程,其中讨论了“无法找到虚拟表的链接器符号......”问题。很少解释为什么存在这个问题,尽管给出了具体例子的一些解决方案。遇到这方面的困难,我想分享我学到的东西。
首先,这个错误消息仅出现在Linux版本中,它没有出现在Windows版本中。 Hmmmm .....
在我的情况下,问题是由同一个线程中的第二次调用非重入方法引起的。一旦我发现问题,通过使用静态忙标志很容易修复,并且只在第二次调用忙时返回。简而言之,这就是问题和解决方案。但是我怎么陷入这个烂摊子?
那么非租赁方法实际上是一个Qt插槽。因为我知道第一次调用(实际上是一个发射)是有可能的,所以连接是用Qt :: QueuedConnection建立的。但是,我后来在功能处理时放了一个闪屏QSplashScreen。我没有意识到QSplashScreen :: repaint()调用了QApplication :: processEvents(),它调度了第二个违规的发射。
所以我可以通过删除QSplashScreen并使用QLabel来解决问题。然而,虽然它们在Windows中运行良好,但实际上在Linux中都不起作用,它们会建立一个半透明窗口而不绘制内容(即使是repaint()和/或processEvents()也不会这样做)。所以这可能是一个Qt Linux漏洞,这是另一个故事.......
也许这本应该贴在其他地方,如果是的话,抱歉......