0

我目前正在学习/使用 c++,但我来自 Java 背景,所以如果这是一个愚蠢的问题,我深表歉意。下面是一些代码,表示我处理由外部 API 生成的错误的方式。但是,我不确定当我为我的错误处理输出参数赋值时是否会导致内存泄漏。

class ExceptionHandler {

private:
    std::string _msg;
    int _code;

public:
    ExceptionHandler(std::string msg = "", int code = 0) : 
         _msg(msg),
         _code(code)
    {
    }

    int code() {
        return _code;
    }
    std::string msg() {
        return _msg;
    }

}

 //This method returns true if it was executed with no errors
 //It returns false if an error occurred

    bool foo(ExceptionHandler * errHandler = NULL) {

        int sts; 

        //The API functions return 0 if completed successfully
        //else they returns some error code

        sts = some_api_func1();

        if(sts != 0) { //An error occurred!
            if(errHandler) {
                ExceptionHandler handler("Error from func1",sts);
                *errHandler = handler; //<--- Will this cause a memory leak since I would be losing errHandler's original value??
            }
            return false;
        }

        //My motivation for using exception handling this way is that I can 
        //set the handler's message based on what part it failed at and the 
        //code associated with it, like below:

        sts = some_api_func2();

        if(sts != 0) { //An error occurred!
            if(errHandler) {
                ExceptionHandler handler("Error from func2",sts); //<--- Different err message
                *errHandler = handler; //<--- But does this cause a memory leak?
            }
            return false;
        }

        return true;
    }


//Main method

int main() {
    ExceptionHandler handler;

    if(!foo(&handler)) {

        std::cout << "An exception occurred: (" << handler.code() << ") " << handler.msg() << std::endl;

    } else {

        std::cout << "Success!" << std::endl;

    }


}
  • 如果发生错误,方法 'foo()' 会导致内存泄漏吗?

  • 如果是这样,我该如何解决?如果没有,怎么没有?

  • 这是处理错误的好方法吗?

先感谢您!

编辑

我了解到上面的代码不会产生内存泄漏,但下面的代码是处理错误的更好方法(谢谢大家!):

void foo() {

    int sts;

    sts = some_api_func1();


    if(sts != 0) 
        throw ExceptionHandler("Error at func1",sts);

    sts = some_api_func2();

    if(sts != 0)
        throw ExceptionHandler("Error at func2",sts);
}

int main() {

    try {
        foo();
        std::cout << "Success!";
    } catch(ExceptionHandler &e) { //<--- Catch by reference
        std::cout << "Exception: (" << e.code() << ") " << e.msg();
    }


}
4

1 回答 1

1
ExceptionHandler handler;
if (!foo(&handler)) {
    //...
}

定义一个具有自动存储持续时间的对象,其地址被传递到foo函数中。顺便说一句,如果你知道你总是将参数传递给函数,那么通过引用而不是指针传递它。

bool foo(ExceptionHandler * errHandler = NULL) {
    ExceptionHandler handler("Error in foo", 1);
    *errHandler = handler;
}

还会创建另一个ExceptionHandler具有自动存储持续时间的实例,因此一旦执行超出范围,该对象就会被销毁。但没关系,因为使用了默认赋值运算符,它将's 数据成员*errHandler = handler;的值复制到指向的对象中,因此在这种情况下没有内存泄漏。handlererrHandler

“这是处理错误的好方法吗?”

不,这不是处理错误的正确方法。改用异常。只要确保您最终不会滥用异常作为通过程序传递数据的另一种方式。所以我建议你也看看:为什么要保守地使用异常?

其他相关问题:
C++ 社区是否就何时应使用异常达成共识?
“我们不使用 C++ 异常”——还有什么选择?让它崩溃?


一旦决定使用异常,请确保按值抛出并按引用捕获

if (...)
    throw MyException(...);

在某处:

try {
    ...
} catch (MyException& e) {
    ...
}
于 2013-02-28T22:43:19.823 回答