什么可能导致运行时“无法在Qt中找到虚拟表的链接器符号...”错误?

问题描述 投票:2回答:2

这个问题以类似的方式被多次提出,例如在stackoverflowforum.qt.ioqtcentre.org。问题是此错误消息非常模糊,以至于一个解决方案无法应用于另一个方案。大多数线程在讨论过程中死了但是:-(

因此,我在Qt应用程序中获得的完整错误消息是:

找不到“OneOfMyClasses”的虚拟表的链接器符号 值找到“QString :: shared_null”而不是

OneOfMyClasses根据各种变化而变化,QString :: shared_null对于我得到的所有错误都保持不变。以下是我的日志记录控制台的屏幕截图:

enter image description here

  1. 为什么字体颜色为粉红色,那么谁打印此邮件?
  2. 为什么我在设置断点并单步执行代码时才会看到此消息?简单地运行应用程序时不会出现此消息。

它发生的位置是在当前位置之前的源行中的此函数(黄色箭头):

enter image description here

所以根据消息,我走进m_pStateWidget->insertNavLabel(...),错误信息打印在Qt内部与QString类相关的构造函数中。所以我尝试了以下方法,将问题从这个代码位置移开:

enter image description here

执行此操作时,我在消息中的另一个类名称下面会显示相同的错误消息,请注意QString :: shared_null保持不变。

在我看来,我有一些腐败的记忆。

  1. 我该如何开始调查这个问题?我害怕更改代码,因为这可能会隐藏上述问题。
  2. 怎么了QString :: shared_null?我发现其他人经常在他们的错误消息中看到相同的内容。

感谢您的任何提示或帮助! :-)

编辑:现在变得非常有趣。我在消息打印之前就已经进入了每一个函数,最后我得到了以下错误消息:

enter image description here

在这个位置:

enter image description here

当我在QtCreator中浏览调用堆栈时,每次在堆栈中选择另一个函数时,都会反复打印错误。

  1. 这是否意味着调试器正在打印消息,而且对我来说解决某些类型的东西真的太愚蠢了或者这是否意味着我遇到了严重的麻烦?
c++ qt linker vtable
2个回答
1
投票

原因:在代码中的某处,您可能会超出实际内存

例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分配给一些未初始化的字符串。


1
投票

在不同的网站上有各种各样的线程,其中讨论了“无法找到虚拟表的链接器符号......”问题。很少解释为什么存在这个问题,尽管给出了具体例子的一些解决方案。遇到这方面的困难,我想分享我学到的东西。

首先,这个错误消息仅出现在Linux版本中,它没有出现在Windows版本中。 Hmmmm .....

在我的情况下,问题是由同一个线程中的第二次调用非重入方法引起的。一旦我发现问题,通过使用静态忙标志很容易修复,并且只在第二次调用忙时返回。简而言之,这就是问题和解决方案。但是我怎么陷入这个烂摊子?

那么非租赁方法实际上是一个Qt插槽。因为我知道第一次调用(实际上是一个发射)是有可能的,所以连接是用Qt :: QueuedConnection建立的。但是,我后来在功能处理时放了一个闪屏QSplashScreen。我没有意识到QSplashScreen :: repaint()调用了QApplication :: processEvents(),它调度了第二个违规的发射。

所以我可以通过删除QSplashScreen并使用QLabel来解决问题。然而,虽然它们在Windows中运行良好,但实际上在Linux中都不起作用,它们会建立一个半透明窗口而不绘制内容(即使是repaint()和/或processEvents()也不会这样做)。所以这可能是一个Qt Linux漏洞,这是另一个故事.......

也许这本应该贴在其他地方,如果是的话,抱歉......

© www.soinside.com 2019 - 2024. All rights reserved.