简体   繁体   English

C++ 虚拟方法引发 EXC_BAD_ACCESS(仅当被 Objective-C++ 调用时)

[英]C++ virtual method raises EXC_BAD_ACCESS (only if called by Objective-C++)

I have the following things as part of a very large codebase:我将以下内容作为非常大的代码库的一部分:

class FooObserver {
public:
     virtual void FooObjectChanged() = 0;
};

class MainStuff :  public FooObserver {
public:
    /* ... */
    void FooObjectChanged();
    void doSomething();
};

void MainStuff::doSomething() {    
    this->FooObjectChanged();
    FooObserver *o = this;
    o->FooObjectChanged();
}

void MainStuff::FooObjectChanged() {
    std::cout << "object changed\n";
}

My understanding of the C++ standard is that this is valid code and FooObjectChanged() would be called twice without any error when doSomething() runs.我对 C++ 标准的理解是,这是有效的代码,当doSomething()运行时, FooObjectChanged()将被调用两次而不会出现任何错误。

But my application fails on the second call.但是我的应用程序在第二次调用时失败了。 (with segfault, or more precisely EXC_BAD_ACCESS on iOS) (带有段错误,或者更准确地说是 iOS 上的EXC_BAD_ACCESS

Another compiler issue is that, If I remove MainStuff::FooObjectChanged() (both the body and its declaration), I would expect the linker to fail with complaints about an abstract class.另一个编译器问题是,如果我删除MainStuff::FooObjectChanged() (主体及其声明),我希望链接器失败并抱怨抽象类。 But compiler does not fail.但是编译器不会失败。 It links and then the program crashes on the first call to the virtual function with它链接,然后程序在第一次调用虚函数时崩溃

libc++abi.dylib: Pure virtual function called!

What is going on?到底是怎么回事? What may cause these problems?什么可能导致这些问题? FooObserver is not a base class of anything else, only of MainStuff . FooObserver不是其他任何东西的基类,只是MainStuff的基类。

  1. Check if there is any other pure virtual function inherited from some other base class in MainStuff and you didn't override in MainStuff 检查是否在MainStuff从其他基类继承了其他纯虚函数,并且没有在MainStuff覆盖
  2. Check doSomething is called on a valid object that is alive and within scope (not destroyed while MainStuff::doSomething() has been called and in processing) 检查doSomething是否在有效且处于范围内的有效对象上调用(在MainStuff::doSomething()并在处理过程中不会销毁)

This turned out to be some problem with XCode. 原来这是XCode的问题。 For some reason it stopped recompiling some of the source files. 由于某种原因,它停止了重新编译某些源文件。 After removing everything from the DerivedData folder and restarting XCode the code compiles, links and runs as I expect. 从DerivedData文件夹中删除所有内容并重新启动XCode之后,代码将按预期进行编译,链接和运行。

I just meet similar issue, where I had multiple (2 or more) C++ private-Classes (ie where Class has no Header), and all with exact same name, but defined in different .mm files.我只是遇到了类似的问题,我有多个(2 个或更多)C++ 私有类(即类没有标题),并且都具有完全相同的名称,但在不同的.mm文件中定义

Sometimes when calling one class's virtual method, Clang decided to use another class's vtable (which's header was NOT even ever included), resulting in binary that calls wrong method-address (and that wrong-method accessed fields, which do simply not exist in class, aka SIGSEG or BAD_ACCESS).有时,当调用一个类的virtual方法时, Clang决定使用另一个类的vtable (它的头甚至从未包括在内),导致二进制调用错误的方法地址(以及错误方法访问的字段,这些字段在类中根本不存在) ,又名 SIGSEG 或 BAD_ACCESS)。

I was shocked, because private-class is a common C++ approach, but changing each private Class's name fixed Objective-C++'s (or rather Clang's) issue.我很震惊,因为私有类是一种常见的 C++ 方法,但是更改每个私有类的名称修复了 Objective-C++(或者更确切地说是 Clang)的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM