C ++程序在退出时崩溃,内存中的访问冲突

时间:2016-12-31 19:44:37

标签: c++ string struct access-violation

我写了一个程序来帮助我跟踪财务状况,我使用一系列结构来处理所有信息并将其写入文件。但是,每次我选择关闭程序的选项时,它都会因两个单独的错误而崩溃。

修改

发生此错误而不在代码中运行任何内容。我打开程序,选择退出,然后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;
}

1 个答案:

答案 0 :(得分:3)

您的Transaction类包含非POD数据(string变量),但随后包含

inFile.read(reinterpret_cast<char *>(&record[c]), sizeof(Transaction));

您尝试从文件中读取它们,就像Transaction个实例是简单的二进制数据块一样。它们并非如此无法运作。这样做恰好会破坏string对象,在这种情况下,当您退出程序时,在事务析构函数期间会发生崩溃。

您需要使用更复杂的方式在文件中写入和读取数据 - 这些内容可以单独正确地访问成员变量。

相关问题