You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

租车程序输入结束日期后触发内存访问错误(0xC0000005)求助

C++租车程序内存访问违规(0xC0000005)问题分析与修复

我的C++租车程序分为Administration、Authentication、Client三个模块,输入租车结束日期后程序短暂冻结,随后抛出错误码-1073741819(对应0xC0000005,内存访问违规)。经调试确认问题出在rentCar和writeRentalCarsToCSV函数中,相关代码如下:

#include "Client.h"
#include <fstream>
#include <sstream>
#include <iostream>

using namespace std;

struct Car {
    string plateNumber;
    string brand;
    int year;
    string model;
    double pricePerDay;
    string color;
};

struct Date {
    string startDate;
    string endDate;
};

struct Rental {
    string idNumber;
    string plateNumber;
    Date d;
};

Car* readCarsFromCSV(const string& filename, int& numCars) {
    ifstream file(filename);
    if (!file.is_open()) {
        cout << "Error: Unable to open " << filename << " for reading." << endl;
        numCars = 0;
        return nullptr;
    }

    Car* cars = nullptr;
    string line;
    int index = 0;
    while (getline(file, line)) {
        if (line.empty()) continue;

        stringstream ss(line);
        if (index == 0) {
            cars = new Car[1];
        }
        else {
            Car* temp = new Car[index + 1];
            for (int i = 0; i < index; ++i) {
                temp[i] = cars[i];
            }
            delete[] cars;
            cars = temp;
        }

        getline(ss, cars[index].plateNumber, ',');
        getline(ss, cars[index].brand, ',');
        string yearStr;
        getline(ss, yearStr, ',');
        bool validYear = true;
        for (char c : yearStr) {
            if (!isdigit(c)) {
                validYear = false;
                break;
            }
        }
        if (validYear && !yearStr.empty()) {
            cars[index].year = stoi(yearStr);
        }
        else {
            cerr << "Invalid year: '" << yearStr << "' in line: " << line << endl;
            cars[index].year = 0;
        }

        getline(ss, cars[index].model, ',');
        string priceStr;
        getline(ss, priceStr, ',');
        try {
            cars[index].pricePerDay = stod(priceStr);
        }
        catch (const invalid_argument& e) {
            if (!priceStr.empty()) {
                cerr << "Invalid price: " << priceStr << " in line: " << line << endl;
            }
            cars[index].pricePerDay = 0.0;
        }
        getline(ss, cars[index].color);
        index++;
    }
    file.close();
    numCars = index;
    return cars;

}



void writeRentalCarsToCSV(const Rental* rentals, int numRentals) {
    ofstream file("C:\\Games\\Car Rental Program\\rentalcars.csv");
    if (!file.is_open()) {
        cout << "Error: Unable to open rentalcars.csv for writing." << endl;
        return;
    }

    file << "User ID,Plate Number,Start Date,End Date" << endl;
    for (int i = 0; i < numRentals; ++i) {

        if (i < numRentals && rentals[i].idNumber != "" && rentals[i].plateNumber != "" && rentals[i].d.startDate != "" && rentals[i].d.endDate != "") {
            file << rentals[i].idNumber << "," << rentals[i].plateNumber << "," << rentals[i].d.startDate << "," << rentals[i].d.endDate << endl;
        }
    }

    file.close();
    cout << "Rented cars data written to rentalcars.csv successfully." << endl;

}


bool checkAvailability(const Rental* rentals, int numRentals, const string& plateNumber, const string& rentedDate) {
    for (int i = 0; i < numRentals; ++i) {
        if (rentals[i].plateNumber == plateNumber && rentals[i].d.startDate <= rentedDate && rentals[i].d.endDate >= rentedDate) {
            return false;
        }
    }
    return true;

}
void rentCar(Rental*& rentals, int& numRentals, const string& plateNumber, const string& startDate, const string& endDate) { //this is where i believe the error is

    if (numRentals < 0) {
        cout << "Error: numRentals is not initialized properly." << endl;
        return;
    }

    if (numRentals % 10 == 0) {
        Rental* temp = new Rental[numRentals + 10];
        if (!temp) {
            cout << "Error: Memory allocation failed." << endl;
            return;
        }
        for (int i = 0; i < numRentals; ++i) {
            temp[i] = rentals[i];
        }
        delete[] rentals;
        rentals = temp;
    }

    rentals[numRentals] = { to_string(numRentals + 1), plateNumber, {startDate, endDate} };
    ++numRentals;

    writeRentalCarsToCSV(rentals, numRentals);
    cout << "Car rented successfully!" << endl;

}

核心问题点

  1. 未初始化的rentals指针
    若调用rentCar前,rentals未被初始化为nullptr而是野指针,numRentals %10 ==0分支中执行delete[] rentals会直接触发内存访问违规,这是导致0xC0000005错误的最可能原因。

  2. 数组边界访问风险
    当numRentals不是10的倍数时,直接访问rentals[numRentals]看似合法,但如果初始内存分配逻辑存在遗漏(比如第一次调用前rentals未分配且numRentals不为0),会导致越界访问。

  3. 冗余代码
    writeRentalCarsToCSV中的if (i < numRentals)判断完全多余,外层循环已限制i的范围,但不会导致崩溃。


修复方案

1. 强制初始化指针与计数器

调用rentCar前必须确保rentals = nullptr且numRentals = 0,同时在rentCar函数开头增加校验:

if (rentals == nullptr && numRentals != 0) {
    cout << "Error: rentals pointer is null but numRentals is non-zero." << endl;
    return;
}
if (rentals != nullptr && numRentals == 0) {
    delete[] rentals;
    rentals = nullptr;
}

2. 优化内存分配逻辑

调整初始分配逻辑,避免空指针与计数器不匹配的问题:

if (numRentals % 10 == 0) {
    int newSize = (numRentals == 0) ? 10 : numRentals +10;
    Rental* temp = new Rental[newSize];
    if (!temp) {
        cout << "Error: Memory allocation failed." << endl;
        return;
    }
    for (int i=0; i<numRentals; ++i) {
        temp[i] = rentals[i];
    }
    delete[] rentals;
    rentals = temp;
}

3. 用标准容器替代手动内存管理

手动管理动态数组极易出错,建议改用std::vector<Rental>彻底规避内存问题:

void rentCar(vector<Rental>& rentals, const string& plateNumber, const string& startDate, const string& endDate) {
    Rental newRental;
    newRental.idNumber = to_string(rentals.size() +1);
    newRental.plateNumber = plateNumber;
    newRental.d.startDate = startDate;
    newRental.d.endDate = endDate;
    rentals.push_back(newRental);
    
    writeRentalCarsToCSV(rentals.data(), rentals.size());
    cout << "Car rented successfully!" << endl;
}

同时修改writeRentalCarsToCSV和checkAvailability的参数为const vector<Rental>& rentals,简化代码逻辑。

内容的提问来源于stack exchange,提问作者Joseph Semaan Sfeir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 09:35:57