Search code examples
c++exceptionsegmentation-faultcoutostream

C++ Segmentation fault after catching exception and calling cout


In my program, I get segmentation fault when calling

cout << ( ball(1,0,0) ).getName();

For testing purposes when i call
( ball(1,0,0) ).getName();

I get an exception as expected and program doesn't crash.

What might be wrong here? I tried overloading ostream but it didn't seem to work. The related parts of the program are:

Ball& Field::operator()(int x, int y, int z){

try{
    if (arr[x][y][z]==1){ // When it's 1, there is a ball in that coord 
        return search(root,x,y,z); // Return ball instance
    }else{

        throw ballException(); // 'Error: Ball not found'
    }
}catch(std::exception &e){
    std::cout << e.what() << std::endl;

}

}

const string& Ball::getName() const {

                try{
                    return this->name;

                }catch(std::exception & e){

                }


}

Ball::Ball(const string& name, const string& type, int size){
this->name =name;
this->type = type;
this->size= size;

}
Ball exception is:

 class ballException: public exception {
virtual const char* what() const throw() {
        return "Error: No Ball in the coordinates!";
}

};


Solution

  • You're not returning anything when you catch an exception:

    Ball& Field::operator()(int x, int y, int z){
        try{
            if (arr[x][y][z]==1){ // When it's 1, there is a ball in that coord 
                return search(root,x,y,z); // Return ball instance
            }else{
                throw ballException(); // 'Error: Ball not found'
            }
        }catch(std::exception &e){
            std::cout << e.what() << std::endl;
        }
        // Nothing is returned.
    }
    

    Unless search also throws an exception, the exception handling is completely pointless, and the code is equivalent to

    Ball& Field::operator()(int x, int y, int z){
        if (arr[x][y][z]==1){ // When it's 1, there is a ball in that coord 
            return search(root,x,y,z); // Return ball instance
        }
        // Returns nothing
    }
    

    Calling getName on that non-existing object may or may not appear to work – it's undefined.
    (And it's more likely that you'll crash when trying to print the name that doesn't exist than if you just reference it.)

    You probably want to handle the exception in the calling code rather than present that code with an object that doesn't exist:

    Ball& Field::operator()(int x, int y, int z){
        if (arr[x][y][z]==1){
            return search(root,x,y,z);
        }else{
            throw ballException();
        }
    }