在构造函数中将实例添加到 std::map 时,C++ 空指针取消引用

问题描述 投票:0回答:1

我正在尝试获取我的 C++ 应用程序的错误代码列表,以便在多个项目之间共享错误。每个错误仅包含一个唯一的代码(用于提供给

exit()
和类似代码)和要显示的消息。除了构造函数和一些转换方法之外,我还需要一些函数来通过其代码获取错误,以便当程序 A 退出时我可以读取程序 B 的返回代码并将其显示给用户/日志/其他内容。显然,这意味着要跟踪整个错误列表。为此,我在 Error 类中保留一个静态
std::unordered_map
,以便 Error 构造函数将正在创建的实例添加到其中。但是,由于某种原因我不太明白,在将
Error
添加到地图时,我不断收到空指针取消引用错误。我的代码如下:

错误代码.h

namespace ErrorCodes{
    class Error{
    private:
        int code;
        std::string message;

        static int counter;

        static std::unordered_map<int, Error*> allErrors;

        Error(int code, std::string message);

    public:
        Error(): code(1), message(""){}

        explicit Error(std::string message);

        Error getByCode(int code);

        operator int() const{
            return code;
        }

        operator std::string() const{
            return message;
        }

        std::ostream& operator<<(std::ostream& os)
        {
            os << std::string("ERR_")+std::to_string(code)+std::string(": ") + message;
            return os;
        }

        operator QString() const{
            return QString::fromStdString(message);
        }

        bool operator == (Error other){
            return other.code == code;
        }


    };

    //List all errors here
    const Error ERR_ERROR_CODE_NOT_FOUND("Couldn\'t find error with code %1"); //Follow QString formatting style for more complex messages
    const Error ERR_GLOBAL_ID_NOT_FOUND("Problem with the global Id, identifier not found.");
    const Error ERR_DIR_NOT_FOUND_OR_CREATED("Dir not found or created, check configuration.");
}

然后是我的 error_codes.cpp:


using namespace ErrorCodes;

int Error::counter = 0;
std::unordered_map<int, Error*> Error::allErrors = std::unordered_map<int, Error*>();

Error::Error(int code, std::string message) : code(code), message(message){
    std::pair pair = std::make_pair(code, this);
    allErrors.emplace(pair); //It fails here
}

Error::Error(std::string message){
    int code = --counter;
    Error(code, message);
}

Error Error::getByCode(int code){
    auto it = allErrors.find(code);
    if(it!=allErrors.end()){
        return *(it->second);
    }else{
        qCritical() << QString(ERR_ERROR_CODE_NOT_FOUND).arg(code);
        exit(ERR_ERROR_CODE_NOT_FOUND);
    }
}

PS:理想情况下,我不会将

Error
创建为一个类,而是一个结构,并拥有某种包含所有错误的集合(例如数组),并允许我通过错误检索它们代码。但是,我没有找到一种方法可以在数组中提供错误并作为“常量”(以便在代码中的任何位置我都可以编写
ErrorCodes::XXX
),而不必手动创建包含所有
Error
的数组s(例如,枚举非常适合此目的)。如果其他人知道更好的方法来做到这一点,我将不胜感激。

c++ error-handling nullptr
1个回答
0
投票

似乎您使用了错误的委托构造函数语法

Error::Error(std::string message){
    int code = --counter;
    Error(code, message); //temporary
}

应该是

Error::Error(std::string message) : Error(--counter, message) {}

否则,您将构造一个临时错误,该错误仅存在于委托构造函数的堆栈帧中,当退出构造函数时,临时错误的“this”指针指向无效的内存区域。

我不太清楚为什么仅使用此代码就可以直接得到分段错误,而不是在尝试从地图中取消引用错误时得到它,但这是一个很好的起点。

© www.soinside.com 2019 - 2024. All rights reserved.