C++ 读/写二进制文件。在程序退出时它给出 System.AccessViolationException

标签 c++ exception c++-cli binaryfiles

这个 C++ 程序是使用 Visual Studio 2010 创建的。这是一个让类的每个人都难过的小组项目。
该程序最初启动良好,用户可以运行该程序并添加写出到文件的项目。项目被读回并显示。
当用户完成后,在程序退出 return 0; 它给我“发生了类型为 System.AccessViolationException 的未处理异常。尝试读取或写保护内存。这通常表示其他内存已损坏。”
发生这种情况时,它会在此处打开一个名为 utility 的文件 => for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter; *_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter) (*_Pnext)->_Myproxy = 0.
我可以通过将 return 0; 替换为 exit(0);
来解决这个问题 我知道这不是真正的解决方法,只是在导致此问题的弹孔上贴上创可贴。
修复(此处使用非常松散)之后,再次运行该程序,它会尝试从文件系统加载数据文件。它正确读取第一项并将其加载到 vector 中,但是当它返回到循环开始时,我们看到弹出相同的异常,发生类型为 System.AccessViolationException 的未处理异常。
这是我们使用 fstream 和二进制 i/o 进行的第一个项目。我们已经完成了一个类似的程序,该程序只是读写字符串而没有任何问题。
我相信这个问题源于 fileHandler 类中的某些东西,但我很难查明是什么导致了这个问题。< br/>非常感谢任何建议/帮助。

这是代码。

stdafx.h

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <sstream>
#include <fstream>
#include <string.h>
#include <string>
#include <vector>
#include <time.h>


Week2.cpp(项目的主文件)

//Week2.cpp *******************

#include "stdafx.h"
#include "fileHandler.h"


using namespace std;
using namespace System;


int main(array<System::String ^> ^args)
{   

fileHandler theFile("store.pkl");
vector<item> itemStack = theFile.getFile();

cout << "SKU  Name  Dept  Vendor    Max Order onHand" << endl;
cout << "-------------------------------------------" << endl;
for (int i = 0; i < itemStack.size(); i++)
{
    cout << itemStack[i].toString() << endl;
}
vector<item> newStack;

//prompt for input
bool doneEditing = false;

while(!doneEditing)
{
    int A;
    int E;
    int F;
    int G;
    string B;
    string C;
    string D;
    string tempString;
    cout << "Enter item info:" << endl << "Item SKU: ";
    cin >> A;
    cout << endl << "Item Name: ";
    cin >> B;
    cout << endl << "Item Dept: ";
    cin >> C;
    cout << endl << "Vendor Name: ";
    cin >> D;
    cout << endl << "Max Number: ";
    cin >> E;
    cout << endl << "Reorder Number: ";
    cin >> F;
    cout << endl << "OnHand Number: ";
    cin >> G;
    cout << endl << "Done?? Y/N: ";
    cin >> tempString;
    cout << endl;

    item tempItem = item(A, B, C, D, E, F, G);
    newStack.push_back(tempItem);

    if (tempString == "Y" || tempString == "y")
    {
        doneEditing = true;
    }
    }
    cout << "Saving stack to file" << endl;
    theFile.putFile(newStack);
    cout << "Items written to file" << endl;

    vector<item> newFileStack = theFile.getFile();

    cout << "After reload: " << endl;
    cout << "SKU  Name  Dept  Vendor    Max Order onHand" << endl;
    cout << "-------------------------------------------" << endl;
    for (int i = 0; i < newFileStack.size(); i++)
    {
    cout << newFileStack[i].toString() << endl;
    }

    cout << "Thank you for using the Awesome Grocery Inventory Application" << endl;

    system("PAUSE");
    /*return 0;   this breaks with same error as 
                  when reading in saved file after application restart 
                  */
    exit(0);
}


item.h

using namespace std;

#pragma once
class item
{
public:
item();
item(int sku, string name, string dept, string vendor, int max, int reorder, int onhand);
~item(void);
string toString();

int ItemSKU() const;
void ItemSKU(int val);
string ItemName() const;
void ItemName(string val);
string VendorName() const;
void VendorName(string val);
int MaxNumb() const;
void MaxNumb(int val);
int ReorderNumb() const;
void ReorderNumb(int val);
int OnHandNumb() const;
void OnHandNumb(int val);

private:
int itemSKU;
string itemName;
string itemDept;
string vendorName;
int maxNumb;
int reorderNumb;
int onHandNumb;
};


item.cpp

#include "StdAfx.h"
#include "item.h"

using namespace std;

item::item()
{

};
item::item(int sku, string name, string dept, string vendor, int max, int reorder, int onhand)
{
itemSKU = sku;
itemName = name;
itemDept = dept;
vendorName = vendor;
maxNumb = max;
reorderNumb = reorder;
onHandNumb = onhand;
}

item::~item(void)
{
}

string item::toString()
{
stringstream ss;
ss << itemSKU << "\t" << itemName << "\t" << itemDept << "\t" << vendorName << "\t" << maxNumb << "\t" << reorderNumb << "\t" << onHandNumb;
string s = ss.str();
return s;
}

int item::ItemSKU() const { return itemSKU; }
void item::ItemSKU(int val) { itemSKU = val; }

string item::ItemName() const { return itemName; }
void item::ItemName(string val) { itemName = val; }

string item::VendorName() const { return vendorName; }
void item::VendorName(string val) { vendorName = val; }

int item::MaxNumb() const { return maxNumb; }
void item::MaxNumb(int val) { maxNumb = val; }

int item::ReorderNumb() const { return reorderNumb; }
void item::ReorderNumb(int val) { reorderNumb = val; }

int item::OnHandNumb() const { return onHandNumb; }
void item::OnHandNumb(int val) { onHandNumb = val; }


fileHandler.h

#include "item.h"

using namespace std;

#pragma once
class fileHandler
{
public:
fileHandler(string);
~fileHandler(void);

vector<item> getFile();
void putFile(vector<item> &);

private:
string theFileName;
};


fileHandler.cpp

#include "stdafx.h"
#include "fileHandler.h"

using namespace std;

fileHandler::fileHandler(string name)
{
theFileName = name.c_str();
}

fileHandler::~fileHandler(void)
{
}


vector<item> fileHandler::getFile()
{
ifstream inFile;
string fileLine;
vector<item> localStack;

inFile.open(theFileName, ios::in|ios::binary);
if (inFile)
{
    cout << "Getting file..." << endl;
    cout << endl;
    // not working on initial load if file is present at start
    inFile.seekg(0);
    while(!inFile.eof())
    {
        item tempItem;
        inFile.read(reinterpret_cast< char * >(&tempItem), sizeof(item));
        localStack.push_back(tempItem);
        cout << "item added to stack" << endl;
    } //breaks from here after reading in 1 item from saved file on reopen
} else {
    ofstream newFile;
    newFile.open(theFileName, ios::out|ios::binary);
    newFile.close();
    cout << "Creating new file..." << endl;
    cout << endl;
    inFile.open(theFileName, ios::in|ios::binary);
}
inFile.clear();
inFile.close();
if (localStack.size() > 0)
{
    //removes some dirty data from end of stack
    localStack.pop_back();
}
return localStack;
}

void fileHandler::putFile( vector<item> &items )
{
ofstream outFile;
outFile.open(theFileName, ios::out|ios::binary);
if(!outFile)
{
    cerr<<"File could not be created"<<endl;
    system("pause");
    exit(1);
}
for (int i = 0; i < items.size(); i++)
{

    outFile.write(reinterpret_cast<const char *>(&items[i]), sizeof(item));
}
outFile.clear();
outFile.close();
}

最佳答案

您不能以这种方式对包含 std::string 成员的对象执行二进制 I/O。 std::string 包含指向为其实际内容动态分配内存的指针。您需要执行某种类型的 serialization反而。通常的建议是 Boost serialization .

关于C++ 读/写二进制文件。在程序退出时它给出 System.AccessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12203842/

相关文章:

c++ - char[] 上的一元运算符

c# - InvalidDataContractException 是无效的集合类型,因为它具有 DataContractAttribute

java - 该定义中的 "leftmost"是什么意思?

c - 回调分配期间出现“无法从...转换”错误(从 C 迁移代码)

c++ - 如何从 QtCreator 的自动完成弹出窗口中隐藏 C++ 私有(private)字段/方法

c++ - STL算法删除容器中的所有对象?

c++ - 是否有用于 80 列格式化文本输出的库/方法?

php - 看起来我们没有 XML 文档

string - 将 String^ 转换为 wstring C++

interop - 为什么非托管结构不能成为托管类的成员?