首页 / 知识
关于c ++:“纯虚函数调用”崩溃来自何处?
2023-04-17 13:40:00

Where do “pure virtual function call” crashes come from?我有时会注意到计算机崩溃的程序出现错误:"纯虚函数调用"。 当无法创建抽象类的对象时,这些程序如何编译? 如果您尝试从构造函数或析构函数进行虚函数调用,则会导致它们。由于您无法从构造函数或析构函数进行虚函数调用(派生类对象尚未构造或已被销毁),因此它调用基类版本,在纯虚函数的情况下,它不会不存在。 (在这里查看现场演示)
除了从具有纯虚函数的对象的构造函数或析构函数调用虚函数的标准情况之外,如果在对象被销毁后调用虚函数,则还可以获得纯虚函数调用(至少在MSVC上) 。显然,尝试这样做是一件非常糟糕的事情,但是如果你正在使用抽象类作为接口而你搞砸了,那么你可能会看到它。如果您使用引用的计数接口并且您有一个引用计数错误或者如果您在多线程程序中有对象使用/对象破坏竞争条件,则可能更有可能...关于这些类型的纯粹调用的事情是它的通常不太容易理解正在发生的事情,因为检查ctor和dtor中虚拟呼叫的"常见嫌疑人"会变得干净。 为了帮助调试这些类型的问题,您可以在各种版本的MSVC中替换运行时库的purecall处理程序。您可以通过使用此签名提供自己的功能来执行此操作:
并在链接运行时库之前链接它。这使您可以控制检测到纯调用时发生的情况。一旦掌握了控制权,就可以做一些比标准处理程序更有用的事情。我有一个处理程序,可以提供purecall发生位置的堆栈跟踪;请参阅此处:http://www.lenholgate.com/blog/2006/01/purecall.html了解更多详情。 (注意,您也可以调用_set_purecall_handler()在某些版本的MSVC中安装处理程序)。 通常当您通过悬空指针调用虚函数时 - 很可能该实例已被销毁。 还有更多"创造性"的原因:也许你已经设法切掉了实现虚拟功能的对象部分。但通常只是实例已经被破坏了。
我遇到了由于被破坏的对象而被调用纯虚函数的场景, 保存在某个地方 仍被引用 对象被调用 Derived类析构函数将vptr点重置为具有纯虚函数的Base类vtable,因此当我们调用虚函数时,它实际调用纯虚函数。 这可能是因为明显的代码错误,或多线程环境中复杂的竞争条件情况。 这是一个简单的例子(关闭优化的g ++编译 - 一个简单的程序可以很容易地优化掉):
堆栈跟踪看起来像:
突出:
如果对象被完全删除,意味着析构函数被调用,并且memroy被回收,我们可能只是在内存返回操作系统时得到 如果你使用Borland / CodeGear / Embarcadero / Idera C ++ Builder,你可以实现
调试时在代码中放置一个断点并在IDE中查看callstack,否则如果你有适当的工具,则在你的异常处理程序(或那个函数)中记录调用堆栈。我个人使用MadExcept。 PS。原始函数调用位于[C ++ Builder] source cpprtl Source misc pureerr.cpp中 我使用VS2010,每当我尝试直接从公共方法调用析构函数时,我在运行时遇到"纯虚函数调用"错误。
所以我把里面的内容~Foo()移动到单独的私有方法,然后它就像一个魅力。
我猜有一个为抽象类创建的vtbl由于某些内部原因(它可能需要某种运行时类型信息)并且出现问题并且真实对象得到它。这是一个错误。仅此一点应该说不可能发生的事情是。 纯粹的猜测 编辑:看起来我在这个案子中错了。 OTOH IIRC有些语言允许vtbl调用构造函数析构函数。 这是一种偷偷摸摸的方式。我今天基本上发生了这件事。
|
最新内容
相关内容
linux调用函数的命令?
linux调用函数的命令?,系统,代码,策略,上调,时间,设计,通信,网络,设备,项目,如何在Linux内核里增加一个系统调用?在一个进程中创建3个线程,名字linux外部命令调用?
linux外部命令调用?,系统,软件,标准,命令,盘中,管理,外部,进程,程序,内存,linux借用外部命令expr,实现计算器功能,利用管道,进程你得装一个callinux怎么调用命令行?
linux怎么调用命令行?,系统,地址,工具,工作,首页,终端,命令,密码,信息,情况,linux怎么打开命令行窗口1、在Linux系统中,打开命令行窗口需要使用浏览器调用linux命令?
浏览器调用linux命令?,系统,信息,人工智能,软件,数据,首次,地址,代码,咨询,服务,求助大神,如何通过网页使用python向linux系统发送一些命令执py调用linux的命令?
py调用linux的命令?,系统,代码,状态,环境,标准,工具,命令,文件,脚本,终端,linux执行python脚本1、先将终端所在路径切换到python脚本文件的目浏览器调用linux命令?
浏览器调用linux命令?,系统,信息,人工智能,软件,数据,首次,地址,代码,咨询,服务,求助大神,如何通过网页使用python向linux系统发送一些命令执py调用linux的命令?
py调用linux的命令?,系统,代码,状态,环境,标准,工具,命令,文件,脚本,终端,linux执行python脚本1、先将终端所在路径切换到python脚本文件的目linux系统命令调用?
linux系统命令调用?,系统,单位,工具,工作,管理,地址,权威,密码,电脑,信息,怎么把linux系统的命令行打开在Linux系统中,打开命令行窗口需要使用linux调用上一条命令?
linux调用上一条命令?,系统,命令,一致,数字,名称,网上,电脑,目录,空格,终端,linux返回上一级的命令是什么?怎么写?首先在电脑中,打开linux系统linux命令行调用程序?
linux命令行调用程序?,工具,环境,代码,初级,工程,系统,网上,服务,管理,发行,linux下如何运行程序?1、,首先去运行perl-v命令查看您的linux系统脚本调用linux命令?
脚本调用linux命令?,代码,系统,工作,底部,脚本,位置,环境,行用,官网,标准,typescript脚本中怎样运行Linux命令?1、Script可用于记录当前用户的调用函数命令linux?
调用函数命令linux?,系统,管理,网络,通用,统一,观察,地址,代码,设备,地方,怎么调用system函数,使用Android的linux命令1、int system(const ch