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

标签 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;
}

最佳答案

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

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

您正在尝试从文件中读取它们,就好像 Transaction 实例是简单的二进制数据 block 一样。他们不是那样行不通。在这样做的过程中,您碰巧破坏了 string 对象,在这种情况下,当您退出程序时,碰巧会在 Transaction 析构函数期间导致崩溃。

您将需要使用更复杂的方式将数据写入文件和从文件读取数据 - 可以单独且正确地访问成员变量的方法。

关于C++程序在退出时崩溃,内存中的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41411255/

相关文章:

c++ - 如何通知我窗口已激活?

javascript - C# 十进制到 C++ float 和 javascript 数字

C++练习煎饼

c++ - 无法将字符串数组声明为类成员

go - 如何将 "sub"结构附加到列表中

c++ - visual studio 6 中的 128 位整数

python - 如何将 0's and 1' 字符串中的字符替换为其他字符

c - scanf 没有正确存储输入

c - C 中的 struct ** 与 struct * 。取消引用和寻址运算符之间的混淆

c++ - C/C++ 结构包装不起作用