C ++读取/写入二进制文件.在程序退出时,它给出System.AccessViolationException [英] C++ read/write to binary file. on program exit it gives System.AccessViolationException

查看:79
本文介绍了C ++读取/写入二进制文件.在程序退出时,它给出System.AccessViolationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此C ++程序是使用Visual Studio 2010创建的.这是一个小组项目,每个班级的人都被困住了.
该程序最初可以正常运行,并且用户可以运行该程序并添加写出到文件中的项目.
当用户完成操作时,在退出 return 0; 的程序上,它给我发生了类型为System.AccessViolationException的未处理异常.尝试读取或写受保护的内存.这通常表明其他内存已损坏."
发生这种情况时,它将在此处打开一个名为实用程序的文件=> for(_Iterator_base12 ** _ Pnext =& _Myproxy-> _ Myfirstiter; * _Pnext!= 0; * _Pnext =(* _Pnext)-> _ Mynextiter)(* _Pnext)->_Myproxy =0.
我可以通过将 return 0; 替换为 exit(0);
来解决此问题我知道这不是真正的解决方案,而只是导致问题的弹孔的创可贴.
修复(在此处非常宽松地使用)之后,然后再次运行该程序,它将尝试从文件系统中加载数据文件.它会正确读取第一个项目并将其正确加载到向量中,但是当它返回到循环的开头时,我们会看到相同的异常弹出,发生了类型为System.AccessViolationException的未处理异常.
这是我们使用fstream和二进制I/O进行的第一个项目.我们曾经通过一个类似的程序来工作,该程序只是在没有任何问题的情况下读写字符串.
我相信问题源于fileHandler类中的某些内容,但很难确定导致此问题的原因.
任何建议/帮助都将不胜感激.

下面是代码.

stdafx.h

This C++ program is created using Visual Studio 2010. It's a group project that has everyone in class stumped.
The program initially starts fine and the user can run through the program and add items that are written out to file. the items are read back in and displayed.
When the user is done, on the program exiting return 0; it gives me "An unhandled exception of type System.AccessViolationException occurred. Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
When this happens it opens up a file called utility here => for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter; *_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter) (*_Pnext)->_Myproxy = 0.
I can fix this by replacing return 0; with exit(0);
I know it's not a real fix though and just a band-aid over a bullet hole that is causing this issue.
After fixing (used very loosely here) that, then running the program again, it attempts to load the data file from the file system. It reads and loads the 1st item into a vector correctly but when it goes back to the start of the loop we see the same exception pop up, An unhandled exception of type System.AccessViolationException occurred.
This is the first project we have worked on using fstream and binary i/o. We had worked through a similar program that was just reading and writing strings w/out any issues.
I believe that the issue stems from something in the fileHandler class but am having a difficult time pinpointing what is causing this issue.
Any advice/help is greatly appreciated.

Here is the code.

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 (the main file for the project)

//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 包含指向其实际内容动态分配的内存的指针.您需要执行某种序列化.通常的建议是 Boost序列化.

You cannot perform binary I/O this way with an object that contains std::string members. A std::string contains pointer(s) to dynamically allocated memory for its actual contents. You need to perform some type of serialization instead. The usual suggestion is Boost serialization.

这篇关于C ++读取/写入二进制文件.在程序退出时,它给出System.AccessViolationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆