C++ unique_ptr 导致应用程序崩溃

标签 c++ unique-ptr

我得到了一个带有一个静态函数的类。目的是为应用程序提供一个通用接口(interface)来检索将记录到特定文件的记录器对象(假设,现在,一个文件不能用不同的文件路径表示法表示)。每个记录器对象都存储在一个映射中,并带有相应的文件名。如果在 config 对象中再次传递相同的文件名,则不会创建新的记录器,而是返回旧的记录器:

typedef std::unique_ptr<AbstractLogger> LoggerPtr_t;
typedef std::map<std::string, LoggerPtr_t >::iterator LoggerMapIt_t;    
std::map<std::string, LoggerPtr_t> LoggerFactory::mLoggerMap;

LoggerPtr_t LoggerFactory::getGenericLogger(const LoggerConfig& config){
    std::string filename = config.getFileName();    
    LoggerMapIt_t itLogger = mLoggerMap.find(filename);    
    if(itLogger == mLoggerMap.end()){
        mLoggerMap.insert(std::make_pair(filename, LoggerPtr_t(new SimpleLogger(config))));
        itLogger = mLoggerMap.find(filename);
    }    
    //if i uncommend the following 4 lines everything works fine
    if(itLogger != mLoggerMap.end()){
        return std::move(itLogger->second);
    }
    else
    return LoggerPtr_t(new SimpleLogger(config));    
}

但如果不同的线程尝试写入同一个记录器,应用程序似乎会崩溃。该文件(表示 std::ofstream)受 SimpleLoggerlog 方法中的互斥锁保护。我猜 unique_ptr 是原因。无论如何,我希望只有一个指向记录器对象的指针,因为该对象的行为就像一个唯一元素(对于每个文件只有一个记录器)。

应用程序崩溃是否可能是由 unique_ptr 引起的?我使用的 unique_ptr 错了吗?是否有更好的解决方案来实现我的意图?


编辑:我对这个问题有很多很好的回答。最后我在我的代码中采用了 Jarod 的解决方案,但是 Joe 的回答也非常有用。

最佳答案

此行将从 std::map

“获取”unique_ptr
if(itLogger != mLoggerMap.end()){
    return std::move(itLogger->second);
}

因此,mLoggerMapitLogger 刚刚指向的 unique_ptr 现在是 nullptr。如果您稍后或从另一个线程返回到该元素,则尝试对该 unique_ptr 执行任何操作都会导致问题,因为您较早地 std::move 指针。

如果您不想放弃指针的所有权,而只想访问指针,您还可以更改函数的签名以返回底层原始指针

AbstractLogger* LoggerFactory::getGenericLogger(const LoggerConfig& config)

然后你可以说

if(itLogger != mLoggerMap.end()){
    return itLogger->second.get();
}

否则,如果您确实想要放弃/将所有权转让给调用者,您应该从 map 中删除该元素,然后返回移动指针。

关于C++ unique_ptr 导致应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34591177/

相关文章:

c++ - 为什么 unique_ptr 有效但 auto_ptr 不适用于 STL

c++ - 采用 unique_ptr 的元素集合,但将它们存储为 shared_ptr 以提供作为 weak_ptr 的访问

c++ - 转让独家所有权 : unique_ptr vs move semantics

c++ - 使用 C++ 和 boost 生成泊松到达日期

c++ - 为什么 std::auto_ptr operator = 垃圾对象?

文件中的 C++ 新行不起作用

c++ - 唯一指针: LValue Reference vs RValue Reference function calls

c++ - 从构造函数中抛出异常 - Core Dumped

c++ - 重载 + 运算符以添加 2 个多项式

c++ - std::unique_ptr<T[]>::reset 在 gcc 6 中的实现