简体   繁体   中英

Segmentation fault when calling a virtual function from an object of the base class

I am getting a segmentation fault (see bottom of the post for the debugger report) when attempting to call a virtual function from an object. I have read every stackoverflow answer and every web article I have found, but none have seemed to address or solve the problem at hand.

See the below code (which mimics my code structure) as an example:

Class declarations.

class A{
public:
    A();
    virtual void foo();
};

class B : A{
public:
    B();
};

class C : B{
public:
    C();
    virtual void foo();
};

Class implementations.

B::B() : A(){

}

C::C() : B(){

}

void A::foo(){

}

void C::foo(){
    // Code specific to class C
}

Function where the seg fault is occurring (the vector declaration is here for reference and is declared and used elsewhere).

std::vector<B*>* vec = new std::vector<B*>();

void bar(){
    if(vec){
        for(auto it = vec->begin(); it != vec->end(); it++){
            if((*it)){ 
                printf("*it is not null\n");
                (*it)->foo();
                printf("Called B::foo()\n");
            }
        }
    }
}

The seg fault occurs at the call to foo() from *it . I have verified that *it is not null as the first debug message is being printed and vec does indeed have contain elements of type C . I added debug messages to C::foo() so I would know when it gets called but it never does and the second debug message in bar() is not printed.

What could be causing the seg fault?

The LLDB error report:

Process 24504 stopped * thread #1: tid = 0x19134f, 0x0000000000000000, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)

frame #0: 0x0000000000000000

error: memory read failed for 0x0

EDIT: Test case: https://gist.github.com/SamTebbs33/5fe56879dc6a423842ad

For some reason the above test case works, even though it reflects my code structure.

EDIT 2: After using Valgrind, I get the following report: https://gist.github.com/SamTebbs33/469eefda95a5006abf64

What I would try is dynamic casting to C pointer:

if ((*it)) {
    printf("*it is not null\n");
    dynamic_cast<C*>(*it)->foo();
    printf("Called B::foo()\n");
}

as there is no other obvious reason of segfault.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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