我写了一个程序来帮助我跟踪财务状况,我使用一系列结构来处理所有信息并将其写入文件。但是,每次我选择关闭程序的选项时,它都会因两个单独的错误而崩溃。
修改
发生此错误而不在代码中运行任何内容。我打开程序,选择退出,然后CRASH @ return 0;
输出-调试
Exception thrown at 0x0121A2D0 in USAA_C.exe: 0xC0000005: Access violation writing location 0x0052004F.
堆栈跟踪
USAA_C.exe!std::_Container_base12::_Orphan_all() Line 222 C++
USAA_C.exe!std::_String_alloc<std::_String_base_types<char,std::allocator<char> > >::_Orphan_all() Line 671 C++
USAA_C.exe!std::_String_alloc<std::_String_base_types<char,std::allocator<char> > >::_Free_proxy() Line 647 C++
USAA_C.exe!std::_String_alloc<std::_String_base_types<char,std::allocator<char> > >::~_String_alloc<std::_String_base_types<char,std::allocator<char> > >() Line 611 C++
USAA_C.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >() Line 1007 C++
USAA_C.exe!Transaction::~Transaction() Line 10 C++
[External Code]
USAA_C.exe!main(int argc, char * * argv) Line 583 C++
[External Code]
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
结构
struct Transaction {
Transaction(){}
~Transaction() {}
int day;
int month;
int year;
char status;
string name;
string method;
string cat;
double amount;
double balance;
};
初始化
const int maxRecs = 1200;
Transaction record[maxRecs];
Transaction temp[maxRecs];
明确打开和关闭的唯一代码 PS:我正在使用VS 2015
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
struct Transaction {
Transaction(){}
~Transaction() {}
int day;
int month;
int year;
char status;
string name;
string method;
string cat;
double amount;
double balance;
};
int main(int argc, char **argv) {
int sel = 0; // Integer option selections
int c = 0; // For loop iterator
int i = 1; // iterator
int count = 0; // Counter
int numRecsYr = 0; // Counts number of records in year array
int day = 0; // System day
int month = 0; // Sytem month
int year = 0; // System year
int fileSize = 0;
int bytesRead = 0;
string filename1 = "usaa_c.dat"; // default data file name
const int maxRecs = 10; // Maximum number of records to load
const int MENU = 7; // Number of menu items
Transaction record[maxRecs]; // Array for transaction records
Transaction temp[maxRecs]; // Temp array for resolving pending transactions
string mMenu[MENU] = {
"Add Transaction\n",
"View Account\n",
"Resolve Pending Transactions\n",
"Calculate Interest\n",
"Export to CSV File\n",
"Save Data\n",
"Exit\n\n" };
ifstream inFile; // file input stream
ofstream outFile; // file output stream
// Initialize the Transaction arrays
for (c = 0; c < maxRecs;c++) {
record[c].day = 0;
record[c].month = 0;
record[c].year = 0;
record[c].status = ' ';
record[c].name = " ";
record[c].method = " ";
record[c].cat = " ";
record[c].amount = 0.0;
record[c].balance = 0.0;
temp[c].day = 0;
temp[c].month = 0;
temp[c].year = 0;
temp[c].status = ' ';
temp[c].name = " ";
temp[c].method = " ";
temp[c].cat = " ";
temp[c].amount = 0.0;
temp[c].balance = 0.0;
}
// Get time info
time_t rawtime = time(NULL);
struct tm* timeinfo = new tm;
localtime_s(timeinfo, &rawtime);
day = timeinfo->tm_mday;
month = timeinfo->tm_mon + 1;
year = timeinfo->tm_year + 1900;
// Set precision for monetary values
cout << setprecision(2) << fixed << showpoint;
// If a .dat does not exist create a new one
// Else, read data into array
do {
inFile.open(filename1, ios::binary);
if (!inFile) {
cout << "File does not exist!\n\n";
system("PAUSE");
break;
}
else {
inFile.seekg(0, inFile.end);
fileSize = (int)inFile.tellg();
inFile.seekg(0, inFile.beg);
for (c = 0; bytesRead < fileSize, c < maxRecs;c++) {
inFile.read(reinterpret_cast<char *>(&record[c]), sizeof(Transaction));
bytesRead += (int)inFile.gcount();
}
inFile.close();
file = true;
break;
}
} while (file != true);
// Count how many records are in the array
for (c = 0; c < maxRecs;c++) {
if (record[c].amount != 0.0) {
count++;
}
}
numRecsYr = count;
// Main Program
do {
system("CLS");
cout << endl << endl;
// Main Menu
cout << "Main Menu\n\n";
i = 1;
for (c = 0; c < MENU;c++) {
cout << i++ << " " << mMenu[c];
}
cin >> sel;
if (sel <= 0 || sel >= 8) {
// Validate input
cout << " - " << sel << " - is not a valid selection! Please try again!\n\n";
system("PAUSE");
break;
}
else if (sel == 1) {
// Add Transaction
}
else if (sel == 2) {
// View Account
}
else if (sel == 3) {
// Resolve Pending Transactions
}
else if (sel == 4) {
// Calculate Interest Rate
}
else if (sel == 5) {
// Export Data to CSV File
}
else if (sel == 6) {
// Save Data to File
do {
system("CLS");
cout << "Saving Data to File...\n\n";
outFile.open(filename1, ios::binary);
if (!outFile) {
cout << "There was an error opening the file!\n\n";
system("PAUSE");
break;
}
else {
for (c = 0; c < numRecsYr;c++) {
outFile.write(reinterpret_cast<char *>(&record[c]), sizeof(Transaction));
}
}
outFile.close();
file = true;
break;
} while (file != true);
}
else if (sel == 7) {
// Exit
cout << "Goodbye!\n\n";
}
} while (sel != 7);
return 0;
}
答案 0 :(得分:3)
您的Transaction
类包含非POD数据(string
变量),但随后包含
inFile.read(reinterpret_cast<char *>(&record[c]), sizeof(Transaction));
您尝试从文件中读取它们,就像Transaction
个实例是简单的二进制数据块一样。它们并非如此无法运作。这样做恰好会破坏string
对象,在这种情况下,当您退出程序时,在事务析构函数期间会发生崩溃。
您需要使用更复杂的方式在文件中写入和读取数据 - 这些内容可以单独正确地访问成员变量。