我正在练习使用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;
}
简化的代码如下所示:
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);
}
任何人都可以给我一个提示,我做错了什么?提前谢谢!
编辑:我的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");
}
}
其中“file”变量是在Open()
中使用的std :: fstream文件答案 0 :(得分: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);
这会导致shared_ptr
有一个悬空指针和一个尝试
<{1}}超出范围时导致delete
,导致错误。
程序已经具有未定义的行为,因为任何尝试访问的代码都是如此
shared_ptr
之后的shared_ptr
取消引用悬空指针。
要更正,请动态分配Read()
:
std::string
或者,更简单,只需返回并存储return boost::make_shared<std::string>(stream.str());
实例:
std::string
因为编译器应该能够使用return value optimization。
请注意,c ++ 11在其中引入了smart pointers,return stream.str();
。