C++ read/write to binary file. on program exit it gives System.AccessViolationException

江枫思渺然 提交于 2021-02-05 09:20:44

问题


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 (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();
}

回答1:


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.



来源:https://stackoverflow.com/questions/12203842/c-read-write-to-binary-file-on-program-exit-it-gives-system-accessviolationex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!