gpt4 book ai didi

c++ - 向/从二进制文件写入/读取 std::set< T >

转载 作者:行者123 更新时间:2023-11-28 06:31:35 25 4
gpt4 key购买 nike

我正在尝试编写一对写/读函数,用于分别存储/检索 std::set< T >数据容器进/出二进制文件。我的writeSet()功能似乎按预期工作,并存储 std::set< T >数据容器没有任何明显的问题。然而 readSet()函数不会,并抛出“未处理的异常 [...] 访问冲突读取位置 0xFEEEFEF6。” main() 之后的异常函数返回 EXIT_SUCCESS .

据我所知(使用 Visual Studio 2013),readSet()实际上似乎成功读取了二进制文件并将数据正确分配给寻址的 std::set< T >数据容器。当 VS2013 崩溃时,它让我有机会中断程序执行,并指出 xtree.h 头文件中的错误。具体来说,调试器提示 _Pnext这条线 || _Ptr != 0 && (*_Pnext)->_Ptr != _Ptr)以下部分:

 #if _ITERATOR_DEBUG_LEVEL == 2
void _Orphan_ptr(_Myt& _Cont, _Nodeptr _Ptr) const
{ // orphan iterators with specified node pointers
_Lockit _Lock(_LOCK_DEBUG);
const_iterator **_Pnext = (const_iterator **)_Cont._Getpfirst();
if (_Pnext != 0)
while (*_Pnext != 0)
if ((*_Pnext)->_Ptr == this->_Myhead
|| _Ptr != 0 && (*_Pnext)->_Ptr != _Ptr)
_Pnext = (const_iterator **)(*_Pnext)->_Getpnext();
else
{ // orphan the iterator
(*_Pnext)->_Clrcont();
*_Pnext = *(const_iterator **)(*_Pnext)->_Getpnext();
}

我的最小工作解决方案如下:

writeSet() : 将 std::set< T > 写入二进制文件

template < class T >
void writeSet(const std::string& filePath, const std::string fileName, std::set<T>& data)
{
// Construct binary file location string using filePath and fileName inputs
std::stringstream file; file << filePath.c_str() << "/" << fileName.c_str();
std::ofstream fileStream; fileStream.open(file.str().c_str(), std::ios::out | std::ios::binary);

// First write number of std::set elements held by data, and then write std::set block to binary file
std::set<T>::size_type n = data.size();
fileStream.write(reinterpret_cast<char*>(&n), sizeof(std::set<T>::size_type));
fileStream.write(reinterpret_cast<char*>(&data), sizeof(T)*n);
fileStream.close();
}

readSet() : 从二进制文件中读取 std::set< T >

template < class T >
void readSet(const std::string& filePath, const std::string fileName, std::set<T>& data)
{
// Construct binary file location string using filePath and fileName inputs
std::stringstream file; file << filePath.c_str() << "/" << fileName.c_str();
std::ifstream fileStream; fileStream.open(file.str().c_str(), std::ios::in | std::ios::binary);


// First read number of elements stored in binary file, then write file content to adresses std::set data variable
std::set<T>::size_type n;
fileStream.read(reinterpret_cast<char*>(&n), sizeof(std::set<T>::size_type));
fileStream.read(reinterpret_cast<char*>(&data), sizeof(T)*n);
fileStream.close();
}

main() : 重现“未处理的异常”错误的最小主函数

#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
#include <string>

int main()
{
// Define binary file read/write directory
const std::string path("C:/data");

// writeSet() testing...
std::set<int> writeSetData;
writeSetData.insert(1); writeSetData.insert(3);
writeSetData.insert(0); writeSetData.insert(2);

writeSet(path, "binaryFile", writeSetData);

// readSet() testing...
std::set<int> readSetData;
readSet(path, "binaryFile", readSetData);

std::cout << "readSetData= {";
for (std::set<int>::iterator it = readSetData.begin(); it != readSetData.end(); ++it){
std::cout << *it << ", ";
} std::cout << "}" << std::endl;

return EXIT_SUCCESS;
}

最佳答案

T 都是你的 POD 吗?否则,制作二进制拷贝几乎没有意义,而不是创建语义拷贝。
此外,set 管理的数据保存在 set 管理的动态分配内存中,而不是 set 本身。
第三点,无论何时您尝试在其中写入任意数量的元素,该空间都不会神奇地增大或缩小。
您必须通过手动插入元素来要求集合增长!

作为旁注,std::string 非常适合字符串连接,没有必要分解 std::stringstream!

关于c++ - 向/从二进制文件写入/读取 std::set< T >,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27434792/

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