1

这个 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 : 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);
}


项目.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;
};


项目.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; }


文件处理程序.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;
};


文件处理程序.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();
}
4

1 回答 1

0

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

于 2012-08-30T19:40:20.930 回答