Search code examples
c++segmentation-faultpolymorphismtype-equivalence

Veryfing that concrete types of polymorphic vector elements are the same


I have got a abstract base class Type which has multiple concrete child classes like Type_bool, Type_int, Type_double etc. Furthermore I construct two vectors of type std::vector<Type*> holding objects of the concrete child classes.

I have implemented the following method to check whether these vectors are the same. In this context same means that they are of the same size and that for all elements in the vectors it holds that type(v1[i]) == type(v2[i]) for all i=1,2, ... v1.size.

bool Env::areArgsTheSame(std::vector<Type*> containedFunArgs, std::vector<Type*> otherFunArgs)
{
    if(containedFunArgs.size() != otherFunArgs.size())
        return false;

    bool argsSame = true;
    for(std::size_t index = 0; index < containedFunArgs.size(); index++) {
        auto *arg = containedFunArgs[index];
        auto *otherArg = otherFunArgs[index];

        if(typeid(*arg) != typeid(*otherArg)){
            argsSame = false;
            break;
        }
    }

    return argsSame;
}

The problem is that whenever I call the function with these to vectors I get a segmentation fault. I've been trying to fix this issue for ages now and can't seem to find a way. Any help is appreciated.

Edit: I was able to narrow down the error to dereferencing in the for loop. But I don't know any other way to access the concrete types.

Edit2: I create containedFunArgs and otherFunArgs in this manner:

     Type_int *a, *b;
     Type_bool* c;

     std::vector<Type*> arguments = {a, b};
     std::vector<Type*> arguments2 = {a, c};

Solution

  • Consider the code...

    Type_int *a, *b;
    Type_bool* c;
    
    std::vector<Type*> arguments = {a, b};
    std::vector<Type*> arguments2 = {a, c};
    

    The pointers a, b, and c are uninitialized. So when you dereference them in Env::areArgsTheSame you invoke undefined behaviour which (in this case at least) results in a seg fault.

    Your pointers need to point to valid instances of their associated types. So you might, for example, do...

    Type_int a, b;
    Type_bool c;
    
    std::vector<Type*> arguments = {&a, &b};
    std::vector<Type*> arguments2 = {&a, &c};
    

    and then pass arguments and arguments2 to Env::areArgsTheSame .