[英]Write/read std::set< T > to/from binary file
我正在嘗試編寫一對寫入/讀取函數,分別用於將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)
|| _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()
:最小的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
本身。
第三點,當您嘗試在其中寫入任意數量的元素時,該空間不會神奇地增長或縮小。
您必須要求通過手動插入元素來擴大集合!
附帶說明一下, std::string
對於字符串連接而言工作得很好,不需要拆散std::stringstream
!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.