【发布时间】:2021-06-26 07:48:30
【问题描述】:
所以我创建了这个程序来将整数向量写入二进制文件,然后再次检索数据。
//vec.cpp
#include <iostream>
#include <vector>
#include <fstream>
template<typename T>
void writeKey(std::string filename, std::vector<T> arr)
{
arr.insert(arr.begin(),(T)arr.size());
std::ofstream write_bin(filename, std::ios::out | std::ios::binary);
if(!write_bin)
{
std::cout << "ERROR: writing vector to file!\n";
exit(1);
}
for(size_t i = 0; i < arr.size(); i++)
{
write_bin.write((char *) &arr[i], sizeof(int));
}
write_bin.close();
if(!write_bin.good())
{
std::cout<<"ERROR: writing time error\n";
exit(1);
}
}
template<typename T>
std::vector<T> readKey(std::string filename)
{
std::ifstream read_bin(filename, std::ios::out | std::ios::binary);
if(!read_bin)
{
std::cout<<"ERROR: reading binary file!\n";
exit(1);
}
size_t limit;
read_bin.read((char*)&limit, sizeof(T));
std::cout<<"limit : "<<limit<<'\n';
std::vector<T> arr(limit,0);
for(size_t i=0; i<limit; ++i)
{
read_bin.read((char*)&arr[i], sizeof(T));
}
read_bin.close();
return arr;
}
int main()
{
std::vector<int> mykey = {5,10,15,20};
writeKey("test.key", mykey);
std::vector<int> mykeys = readKey<int>("test.key");
for(auto e: mykeys)
std::cout<<e<<' ';
std::cout<<'\n';
return 0;
}
所以你看我在这里所做的是我编译了只调用 writeKey() 函数的程序然后运行它......它运行完美的程序
int main()
{
std::vector<int> mykey = {5,10,15,20};
writeKey("test.key", mykey);
return 0;
}
然后我再次编译它,但这次我只调用 readkey() 函数,然后我运行它,它再次按预期运行
int main()
{
std::vector<int> mykeys = readKey<int>("test.key");
for(auto e: mykeys)
std::cout<<e<<' ';
std::cout<<'\n';
return 0;
}
当我在 main() 函数中调用这两个函数时出现问题,然后在此处编译并运行它 readkey 函数中的限制变量具有某种溢出值,而不是我在开头插入的值writekey函数中的向量
int main()
{
std::vector<int> mykey = {5,10,15,20};
writeKey("test.key", mykey);
std::vector<int> mykeys = readKey<int>("test.key");
for(auto e: mykeys)
std::cout<<e<<' ';
std::cout<<'\n';
return 0;
}
这里发生了什么?我该如何解决这个问题?
这是我的编译标志:g++ -o vec.o vec.cpp -Wall -Wextra -fsanitize=address
【问题讨论】:
-
好像是size_t的限制;当我在 main() 中将这两个函数一起调用时是不对的,为什么会这样?
-
write_bin.write((char *) &arr[i], sizeof(int));为什么使用sizeof(int)而不是sizeof(T)?另外为什么要通过副本而不是通过 const ref 传递向量?另外最好不要使用 c 风格的演员表;请改用static_cast/reinterpret_cast。 -
还有一个“小问题”,您正在向文件写入(签名)
int并将此数据读取到size_t,这可能使用不同的数字除了无符号之外的字节数。让我们考虑int使用32位和size_t使用64位的情况:由于size_t limit没有初始化,它可能包含任意数据,但是你只在读取文件时覆盖数据的前32位;此外,即使您在大端机器上将limit初始化为 0,您也只是将值乘以 2^32... -
@fabian 如您所见,我在向量的开头插入了一个元素,这就是为什么我传递了它的副本,因为我不想更改原始向量,将 (int) 更改为(T) 也没有帮助,static_cast 和 reinterpret_cast 也没有解决,我也尝试过使用 unsigned long 作为向量类型,但是当我在 main() 函数中同时调用这两个函数时仍然出现相同的错误
-
“它抛出一个错误”什么错误?
标签: c++ fstream binaryfiles stdvector