为什么我得到一个EXC坏访问错误,当我试图实现这个动态数组



如果我提供的还不够,请让我知道我是否需要提供更多/不同部分的程序。

我还在用Airline类编写程序。Airline类包含一个动态Flight对象数组的变量。

在我的Airlines类中(不能编辑或更改,这些是分配给我的头文件):

//Airline.h    
class Airline {
public: 
    Airline();              // default constructor
    Airline(int capacity);  // construct with capacity n
    void cancel(int flightNum);     
    void add(Flight* flight);
    Flight* find(int flightNum);
    Flight* find(string dest);
    int getSize();

private:
    Flight **array;        // dynamic array of pointers to flights
    int capacity;          // maximum number of flights
    int size;              // actual number of flights
    void resize();
};

//Flight.h
    class Flight {
public:
    Flight();
    // Default constructor
    Flight(int fnum, string destination);     
    void reserveWindow();    
    void reserveAisle();
    void reserveSeat(int row, char seat);
    void setFlightNum(int fnum);
    void setDestination(string dest);
    int getFlightNum();
    string getDest();
protected:
    int flightNumber;
    bool available[20][4];    //only four seat types per row; only 20 rows
    string destination;
 };

//Airline.cpp
#include "Airline.h"
/*  Flight **array;        // dynamic array of pointers to flights
    int capacity;          // maximum number of flights
    int size;              // actual number of flights
*/
Airline::Airline(){
    capacity = 1;     
    size = 0;     
    array = new Flight*[1]; 
}
Airline::Airline(int cap){
    capacity = cap;
    size = 0;
    array = new Flight*[capacity];
    //array = &arr;
}
void Airline::cancel(int flightNum){
    for(int i = 0; i < size; i++){
        if(array[i]->getFlightNum() == flightNum){
            array[i] = NULL;
        }
    }
}
    // Delete the flight with the given flight number.
    // Print "Flight cancelled" if successful, or print
    // "No such flight", if the flight cannot be found.
void Airline::add(Flight* flight){
    if(size >= capacity){
        resize();
    }
    array[size] = flight;
    size++;
    cout << array[size]->getFlightNum(); //This is where the EXC BAD ACCESS is. I set the index of the array to point to the address of the flight I sent in, but I can't access it after that...
}
    // Add the given flight to the array.  If there is no room,
    // double the array capacity and copy the existing flights.
    // When increasing the capacity, print "Capacity increased to N",
    // where N is the new capacity.
Flight* Airline::find(int flightNum){
    for(int i = 0; i < size; i++){
        cout << array[i]->getFlightNum();
        if(array[i]->getFlightNum() == flightNum){
            return array[i];
        }
    }
        return 0;
}
    // Return pointer to flight with given number if present, otherwise
    // return 0.
Flight* Airline::find(string dest){
    for(int i = 0; i < size; i++){
        if(array[i]->getDest() == dest){
            return array[i];
        }
    }
        return 0;
}
    // Return pointer to flight with given destination if present, 
    // otherwise return 0.
int Airline::getSize(){
    return size;
}
    // Returns the number of Flights in the array.
void Airline::resize(){
    Flight **temp = new Flight*[capacity * 2];
    Flight **swapper;
    for(int i = 0; i < capacity; i++){
        temp[i] = array[i];
    }
    swapper = temp;
    temp = array;
    array = swapper;
    delete [] temp;
    capacity *= 2;
    cout << "Capacity increased to " << capacity << endl;
}
    // resizes the array if it exceeds capacity.  New array is double size of old array.

//Flight.cpp
#include "Flight.h"
/*  int flightNumber;
    bool available[20][4];    //only four seat types per row; only 20 rows
    string destination;
*/

Flight::Flight(){
    flightNumber = 0;
    destination = "X";
    for(int i = 0; i < 20; i++){
        for(int j = 0; j < 4; j++)
            available[i][j] = false;
    }
}
    // Default constructor
Flight::Flight(int fnum, string dest){
    flightNumber = fnum;
    destination = dest;
    for(int i = 0; i < 20; i++){
        for(int j = 0; j < 4; j++)
            available[i][j] = false;
    }
}
    // initialize flight with flight number and destination
void Flight::reserveWindow(){
    int i, j;
    char seat;
        bool reserved = false;
            for(i = 0; i < 20; i++){
                for(j = 0; j < 4; j++){
                    if (j == 0 || j == 3){
                        if(!available[i][j] && !reserved){
                            available[i][j] = true;
                            reserved = true;
                            break;
                        }
                    }
                }
                if(reserved)
                    break;
            }
    if (!reserved) {
        cout << "Not available" << endl;
    }else
        switch (j) {
            case 0:
                seat = 'A';
                break;
            case 4:
                seat = 'D';
                break;
            default:
                break;
        }
    cout << "Reserved " << i << seat << endl;
}
    // If a window seat if available, reserve the first available
    // seat, and print it.  The first available seat is the 
    // lowest-numbered one in the lowest numbered row. Seat 0, is
    // A, since 1 is B, and so on.
    // If the seat reserved is 7D, for example, print "7D".
    // If no such seat is available, print "Not available".
void Flight::reserveAisle(){
        bool reserved = false;
    int i, j;
    char seat;
        for(i = 0; i < 20; i++){
                for(j = 0; j < 4; j++){
                    if (j == 1 || j == 2){
                        if(!available[i][j] && !reserved){
                            available[i][j] = true;
                            reserved = true;
                            break;
                        }
                    }
                }
            if(reserved)
                break;
        }
    if (!reserved) {
        cout << "Not available" << endl;
    }else
        switch (j) {
            case 1:
                seat = 'B';
                break;
            case 2:
                seat = 'C';
                break;
            default:
                break;
        }
        cout << "Reserved " << i << seat << endl;
}
    // Just like reserveWindow, but for aisle seats. 
void Flight::reserveSeat(int row, char seat){
        bool reserved = false;
    if (row > 20 || row < 1 || seat > 'D' || seat < 'A') {
        cout << "No such seat." << endl;
        return;
    }
        for(int i = 0; i < 20; i++){
                for(int j = 0; j < 4; j++){
                        if(!available[i][j] && !reserved){
                            available[i][j] = true;
                            reserved = true;
                            break;
                        }
                    }
            if(reserved)
                break;
        }
    if (!reserved) {
        cout << "Not available" << endl;
    }else
        cout << "Reserved " << row << seat << endl;
}
    // Reserve the seat specified if available.  If it is available,
    // print it as in reserveWindow.  
    // If it does not exist, print "No such seat".  
    // If it exists, but is unavailable, print, "Not available".
void Flight::setFlightNum(int fnum){
    flightNumber = fnum;
}
    //assign the flight number for this flight
void Flight::setDestination(string dest){
    destination = dest;
}
    //assign the destination (airline code) for this flight
int Flight::getFlightNum(){
    return flightNumber;
}
    // Return the flight number
string Flight::getDest(){
    return destination;
}
    // Return the destination

//main.cpp
#include "Airline.h"
#include "Flight.h"
#include <fstream>
#include <iomanip>

using namespace std;
int main(){
    ifstream in;
    Airline airline(10);
    Flight flight;
    Flight* flightTemp;
    string transaction;
    string transType;
    int flightNum;
    string flightDest;
    string seatType;
    int seatRow;
    char seatCol;
    string dummy;
    in.open("input4.txt");
    if(!in){
        cout << "File not found. Ending program." << endl;
        return 1;
    }
    while(in >> transaction){
        if(transaction == "ADD"){
            in >> dummy >> flightNum >> dummy >> flightDest;
            //flight(flightNum,flightDest);
            flight.setFlightNum(flightNum);
            flight.setDestination(flightDest);
            airline.add(&flight);
            cout << flight.getFlightNum(); //It works here...
        }
        else if(transaction == "CANCEL"){
            in >> dummy >> flightNum;
            airline.cancel(flightNum);
        }else{
            in >> transType;
            if(transType == "Flight"){
                in >> flightNum;
                cout << flightNum;
                flightTemp = airline.find(flightNum);
            }else{
                in >> flightDest;
                flightTemp = airline.find(flightDest);
            }
        in >> seatType;
        if(seatType == "Seat"){
            in >> seatRow >> seatCol;
            flightTemp->reserveSeat(seatRow - 1, seatCol - 1);
        }else if(seatType == "Aisle"){
            flightTemp->reserveAisle();
        }else
            flightTemp->reserveWindow();
        }
    }
    in.close();
    cin.get();
    return 0;
}

编辑我添加了我所有的代码只是为了让它更容易。

我现在遇到的问题是,当我运行尝试访问flightNum(或任何getter方法)在我的数组中的飞行。我将数组的索引设置为指向我在add()方法中发送的航班的地址,但此后我无法访问它…

使用构造函数:

Airline::Airline(){
    capacity = 1;
    size = 0;
    Flight* arr = new Flight[capacity];
    array = &arr;
}

这是什么?

Flight* arr = new Flight[capacity];
array = &arr;

分配array的方式与resize相同:

Airline::Airline(){
    capacity = 1;
    size = 0;
    array = new Flight*[1];
}

由于array一个 Flight*的数组,而不是指向 Flight的数组的指针

EDIT:编辑后,代码中出现了另一个问题:

void Airline::add(Flight* flight){
    if(size >= capacity){
        resize();
    }
    array[size] = flight;
    size++;
    cout << array[size]->getFlightNum(); 
}

当你打印航班号时,你在增加size之后做array[size]->getFlightNum();。交换size++cout << array[size]->getFlightNum();:

void Airline::add(Flight* flight){
    if(size >= capacity){
        resize();
    }
    array[size] = flight; 
    cout << array[size]->getFlightNum();
    size++;
}

EDIT2:您的Airline::cancel函数也有问题:

void Airline::cancel(int flightNum){
    for(int i = 0; i < size; i++){
        if(array[i]->getFlightNum() == flightNum){
            array[i] = NULL;
        }
    }
}

你不能仅仅将数组中的位置设置为NULL来从数组中删除Flight。一种常用的方法是用数组的最后一个元素替换该位置,然后递减大小:

void Airline::cancel(int flightNum){
    for(int i = 0; i < size; i++){
        if(array[i]->getFlightNum() == flightNum){
            array[i] = array[--size];
        }
    }
}

Flight::reserveWindow也会导致segfault,并且很可能代码中还有更多的错误。因为这是作业,我就不打扰你了。

听起来你写的东西超出了数组的边界。我有一种感觉,问题就在这里:

if(size == capacity)
{         
   resize();     
} 

看看你的情况。如果大小大于容量会发生什么?在这种情况下,它不会调整大小!

最新更新