在结束范围后,提升共享指针"运行时错误"

Sil*_*lex 0 c++ boost shared-ptr

我正在练习使用boost,现在我正在测试boost共享指针.我有一个可以读取文件的Util类.读完文件后,我的"Read"方法返回一个指向文件内容的boost :: shared_ptr.然后我将这个共享指针传递给我的Parser类,它逐行解析字符串.解析完成后,然后在我的Parser类构造函数的末尾(在'}'),我得到一个"运行时错误",它指向一个boost头文件.更具体地说,check_delete.hpp到"删除x"行:

template<class T> inline void checked_delete(T * x) {
   // intentionally complex - simplification causes regressions
   typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
   (void) sizeof(type_must_be_complete);
   delete x;
}
Run Code Online (Sandbox Code Playgroud)

简化的代码看起来像这样:

class File {
    string _path;
public:
    File(string path)
    ~File()
    void Open();
    boost::shared_ptr<string> Read();
    void Close();
};

class Parse {
public:
    Parse(string path) {
        File file = File(path);
        file.Open();
        boost::shared_ptr<string> fileContentPtr = file.Read();
        StartParsing(fileContentPtr);
        file.Close();
    }
    ~Parse();
    StartParsing(boost::shared_ptr<string> fileContentPtr);
};

int main() {
string path = "<some path to my file>";
Parse(path);
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以给我一个提示,我做错了什么?提前致谢!

编辑:我的Read()函数:

boost::shared_ptr<string> File::Read() {
    if(file.is_open()) {
        ostringstream stream;
        stream << file.rdbuf();
        string content = stream.str();
        boost::shared_ptr<string> contentPtr(&content);
        return contentPtr;
    }
    else {
        throw std::runtime_error("File isn't opened");
    }
}
Run Code Online (Sandbox Code Playgroud)

其中"file"变量是在Open()中使用的std :: fstream文件

hmj*_*mjd 5

boost::shared_ptr必须动态分配包含的对象,显式地通过new或隐式地通过boost::make_shared<>.来自boost::shared_ptr:

shared_ptr类模板存储指向动态分配对象的指针,通常使用C++ new-expression.当指向它的最后一个shared_ptr被销毁或重置时,保证删除指向的对象.

在这种情况下,std::string实例是堆栈分配的,并且在Read()返回时将被销毁:

string content = stream.str();
boost::shared_ptr<string> contentPtr(&content);
Run Code Online (Sandbox Code Playgroud)

这导致shared_ptr有一个悬空指针,并在超出范围delete时尝试它shared_ptr,导致错误.

程序已经有未定义的行为,因为任何试图访问shared_ptrafter的代码Read()都会取消引用悬空指针.

要纠正,动态分配std::string:

return boost::make_shared<std::string>(stream.str());
Run Code Online (Sandbox Code Playgroud)

或者,更简单,只需返回并存储std::string实例:

return stream.str();
Run Code Online (Sandbox Code Playgroud)

因为编译器应该能够使用返回值优化.


需要注意的是C++ 11个引入了智能指针,std::shared_ptr在他们之中.