捕获异常并调用cout后的C ++ Segmentation错误

时间:2017-05-06 14:46:08

标签: c++ exception segmentation-fault cout ostream

在我的程序中,调用

时出现分段错误

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

为了测试目的,我打电话给  ( ball(1,0,0) ).getName();

我得到了预期的异常,程序没有崩溃。

这里可能有什么问题?我试着超载ostream,但它似乎没有工作。该计划的相关部分是:

球&安培; 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&amp; 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;

}
球例外是:

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

};

2 个答案:

答案 0 :(得分:1)

当您发现异常时,您没有返回任何内容:

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.
}

除非search也抛出异常,否则异常处理完全没有意义,代码等同于

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
}

在该不存在的对象上调用getName可能会或可能不会正常工作 - 它未定义。
(而且,当您尝试打印不存在的名称时,您更可能会崩溃,而不是仅仅引用它。)

您可能希望在调用代码中处理异常,而不是使用不存在的对象来呈现该代码:

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

答案 1 :(得分:0)

当你捕获异常时,foo(0)是否仍然返回一个可以调用getName()的对象?

要使用这种语法,通常必须返回一个实现getName()的空(通常是静态)对象,或者在退出函数之前确保对象的状态。总体思路如下:

#include <exception>
#include <iostream>
#include <string>

class SomeObject
{
public:
    SomeObject(const std::string& name):_name(name)
    {
    }
    const std::string&  getName() const
    {
        return _name;
    };

    static const SomeObject& getEmpty()
    {
        static SomeObject _empty("");
        return _empty;
    };
private:

    std::string _name;

};


const SomeObject *function( bool throw_exception)
{
    SomeObject * NeverConstructed = 0;
    try {
        if ( throw_exception )
            throw std::runtime_error("oops");
    } catch ( const std::runtime_error& e) {
        std::cout << e.what() << std::endl;
        return &SomeObject::getEmpty();
    }

    return NeverConstructed; // will crash
}

int main(){

    std::cout << (function( true ))->getName() << std::endl;
    return 0;
}