当我从文件中加载序列化时,为啥我的向量充满结构的大小如此之大?
Posted
技术标签:
【中文标题】当我从文件中加载序列化时,为啥我的向量充满结构的大小如此之大?【英文标题】:Why is the size of my vector full of structs so large when I load it's serialization in from a file?当我从文件中加载序列化时,为什么我的向量充满结构的大小如此之大? 【发布时间】:2009-04-02 07:38:16 【问题描述】:正如你们中的大多数人可能已经知道我的一系列问题一样,我正在尝试创建一个程序,该程序可以将多个结构序列化为 .dat 文件,通过加载序列化将它们读回,编辑内容,然后然后将它们重新写入文件等等。这是我正在尝试做的一个库存计划,但我无法让它终生发挥作用。
我正在加载的文件是空白的。我的程序甚至需要 10 秒才能加载,现在我知道为什么了。这是因为我的向量的大小是 25 万。哦等等……这次我运行它,我的向量大小是 5,172,285。那是一个非常大的充满结构的向量。没有任何运行时或编译错误,但我很确定我做错了什么。我正在加载的文件也是完全空白的。
代码:
// Project 5.cpp : main project file.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace System;
using namespace std;
#pragma hdrstop
int checkCommand (string line);
template<typename T>
void writeVector(ofstream &out, const vector<T> &vec);
template<typename T>
vector<T> readVector(ifstream &in);
struct InventoryItem
string Item;
string Description;
int Quantity;
int wholesaleCost;
int retailCost;
int dateAdded;
;
int main(void)
cout << "Welcome to the Inventory Manager extreme! [Version 1.0]" << endl;
ifstream in("data.dat");
if (in.is_open()) cout << "File \'data.dat\' has been opened successfully." << endl; else cout << "Error opening data.dat" << endl; return 0;
cout << "Loading data..." << endl;
vector<InventoryItem> structList = readVector<InventoryItem>( in );
cout <<"Load complete." << endl;
while (1)
string line = "";
cout << "There are currently " << structList.size() << " items in memory.";
cout << endl;
cout << "Commands: " << endl;
cout << "1: Add a new record " << endl;
cout << "2: Display a record " << endl;
cout << "3: Edit a current record " << endl;
cout << "4: Exit the program " << endl;
cout << endl;
cout << "Enter a command 1-4: ";
getline(cin , line);
int rValue = checkCommand(line);
if (rValue == 1)
cout << "You've entered a invalid command! Try Again." << endl;
else if (rValue == 2)
cout << "Error calling command!" << endl;
else if (!rValue)
break;
system("pause");
return 0;
int checkCommand (string line)
int intReturn = atoi(line.c_str());
int status = 3;
switch (intReturn)
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
status = 0;
break;
default:
status = 1;
break;
return status;
template<typename T>
void writeVector(ofstream &out, const vector<T> &vec)
out << vec.size();
for(vector<T>::const_iterator i = vec.begin(); i != vec.end(); i++)
out << *i;
ostream &operator<<(ostream &out, const InventoryItem &i)
out << i.Item << i.Description;
out << i.Quantity;
out << i.wholesaleCost << i.retailCost;
out << i.dateAdded;
return out;
istream &operator>>(istream &in, InventoryItem &i)
in >> i.Item >> i.Description;
in >> i.Quantity;
in >> i.wholesaleCost >> i.retailCost;
in >> i.dateAdded;
return in;
template<typename T>
vector<T> readVector(ifstream &in)
size_t size;
in >> size;
vector<T> vec;
vec.reserve(size);
for(unsigned int i = 0; i < size; i++)
T tmp;
in >> tmp;
vec.push_back(tmp);
return vec;
谁能简单地告诉我如何将其转换为一个程序,该程序实际上可以将充满结构的序列化向量写入文件,然后将它们读回,以便我可以编辑它们并将它们存储回去以供以后加载?哦,我的天哪,这是一次多么愉快的旅程!
感谢您提供的任何帮助!
【问题讨论】:
最好自己做作业 关于作业主题的问题可以提问,礼仪不是解决问题的全部,只是针对问题给出提示和建议。如果在您尝试学习时根本没有任何帮助,这可能会令人沮丧 【参考方案1】:你说文件实际上是空的。 readVector 的第一行是这样的:
in >> size;
你认为最终的尺寸会是多少?由于它是空的,这将导致您没有检测到的错误。变量size
将保持未初始化状态 - 因此您会在其中看到奇怪的值,因为它采用了当时内存中发生的任何值。您可以使用检查来检查流的状态:
if (in)
在布尔上下文中处理它会告诉您是否发生错误 - 这也将涵盖诸如无法读取有效整数变量之类的问题。我建议您应该弄清楚如何在调试器中运行您的程序,您将能够单步执行您的代码并查看给定时间变量的值。
【讨论】:
我试过 if (in) in >> size; 其他 大小 = 0;但我仍然遇到同样的问题。这是您建议的解决方法吗? 不完全是。错误状态是在您尝试从流中读取之后设置的,而不是之前 那是什么意思? 更准确地说,在您完成in >> size
行(或尝试从流中读取任何其他类型)之后,设置了错误状态 - 您应该在每次尝试读取后检查状态【参考方案2】:
所以如果你的文件是空白的并且你正在做:
size_t size; in >> size; vector<T> vec; vec.reserve(size);
你认为会发生什么?大小无法读取,使用随机值
【讨论】:
如何防止这种情况发生? 查看 1800 INFORMATION 帖子和 cmets【参考方案3】:如果您的输入文件为空,则vector
应为空。你不应该越界:
if (in.is_open())
-- 你的程序(当我在我的机器上运行它时)退出。
你能解释一下为什么会有以下问题吗?
#include <String>
using namespace System;
#pragma hdrstop
最容易实现的是一次性读入文件内容,将项目保存在内存中,在内存中编辑它们,然后通过编辑一次写入文件。从内存占用或性能的角度来看,这当然不是一个很好的技术。但是,您要解决的问题并非微不足道。阅读FAQ 36 以更好地了解您的任务。
【讨论】:
哦,废话。那是因为文件开头的 if(file.is_open) 抱歉【参考方案4】:您正在使用空白文件,但是当您加载文件时,您正在寻找一个大小。当文件在文件中没有大小时,您可能会将垃圾放入您的大小变量中。
所以尝试在“data.dat”文件的第一行输入一个零。
编辑: 上述建议只是一个临时修复。你可以试试这个:
in >> size;
//input operation failed
if(in.fail())
//return, or whatever you need to do
【讨论】:
我认为这可能不太对,编写代码以使其可以处理空文件不是更好吗? 我同意。我更建议将其作为临时解决方案...我应该提到这一点。糟糕! 谢谢你,这就是我的要求。我添加了它,它起作用了。以上是关于当我从文件中加载序列化时,为啥我的向量充满结构的大小如此之大?的主要内容,如果未能解决你的问题,请参考以下文章
当我尝试在 Android NDK 中加载冻结模型时,为啥没有注册操作?