gpt4 book ai didi

c++ - unique_ptr 丢失范围时读取访问冲突

转载 作者:行者123 更新时间:2023-11-30 03:16:39 24 4
gpt4 key购买 nike

我正在使用 std::ifstream 从二进制文件中读取一个 char 数组,然后将 char 数组重新解释为指向我的结构的指针,然后将其设为 unique_ptr。一切正常,除非 unique_ptr 超出范围,我会遇到读取访问冲突。

我是不是做错了?我不确定为什么会发生错误。我只有一个关于该数据的 unique_ptr。

我已经包含了产生错误的代码的最基本版本。

struct mystruct {
int val = 0;
double val2 = 5.6;
std::string string = "test";

};

int main()
{

//brackets here just to encapsulate the scope for this example
{
//try to open the stream for reading
std::ifstream stream;
stream.open("test.bin", std::ios::binary | std::ios::in);

char* buffer = new char[sizeof(mystruct)];
stream.read(buffer, sizeof(mystruct));

mystruct * pointer = reinterpret_cast<mystruct*>(buffer);
std::unique_ptr<mystruct> obj = std::unique_ptr<mystruct>(pointer);

//ha no problem reading the struct data
std::cout << "read back: " << obj->string << endl;

stream.close();
}

//obj goes out of scope and throws a read access violation
}

我希望 unique_ptr 只删除对象并且不会抛出任何错误

************编辑*********************
感谢您的评论和回答 - 基本上是在您的帮助下,我生成了我尝试这样做的代码,因此已在此处列出,以防它对其他人有帮助。
要点是:
* 如果从二进制读取和写入,则不建议在结构中使用 std::string,因为 std::string 的字节数未知。
* 需要在将指针分配给它之前在内存中创建对象 - std::make_unique() 适合于此。

struct mystruct {
int val1 = 0;
double val2 = 5.6;
char somestring[10] = "string";

};

int main()
{

//brackets here just to encapsulate the scope for this example
{
//try to open the stream for reading
std::ifstream stream;
stream.open("test.bin", std::ios::binary | std::ios::in);

//hold the results in a vector
auto results = std::vector<std::unique_ptr<mystruct>>();

//read a vectory or mystructs from the binary file
while (!stream.eof())
{
//create the object - NOTE: make_unique initialises my struct
std::unique_ptr<mystruct> obj = std::make_unique<mystruct>();

//read from binary file into obj
if (!stream.read(reinterpret_cast<char*>(obj.get()), sizeof mystruct))
break;

//add the obj to th vector
results.push_back(std::move(obj));
}

stream.close();

for (auto& val : results)
{
cout << "read back: " << val->somestring << endl;
}


}
}

最佳答案

您的代码中存在 3 种未定义的行为。

首先,您假装在一个实际上没有物体的地方有一个物体。您从未创建过 mystruct;你刚刚分配了一些内存字节。仅执行 reinterpret_cast 不足以创建 mystruct。因此,任何访问不存在的“对象”的 pointer 的使用都是 UB。

其次,即使那个缓冲区中有一个,mystruct 也不是可简单复制的,因此您不能只是复制它的字节。您不能将一堆字节读入非平凡可复制的对象中。非平凡可复制的非静态数据成员(即:mystruct::string)的存在使其不可平凡复制。

第三,你尝试删除这个mystruct。但是没有mystruct,你正在删除一个不存在的东西。从技术上讲,#1 可能涵盖了这一点,但这可能是导致您的代码彻底崩溃的原因。

如果您知道为什么“读取结构数据没有问题”碰巧起作用,std::string 实现使用小字符串优化的可能性很大,它将字符串存储在 std::string 本身,如果它足够小的话。对于小字符串,执行按字节复制可能足以“工作”以允许您读取字符串数据。

但这只是走运而已。

关于c++ - unique_ptr 丢失范围时读取访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56179228/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com