当我尝试实现这个动态数组时,为什么会出现EXC BAD ACCESS错误?

时间:2011-10-25 20:49:23

标签: c++ dynamic-data

如果我提供的内容还不够,我是否需要提供我的计划的更多/不同部分。

我还在使用Airline课程开展我的课程。 Airline类包含一系列动态Flight对象的可移动性。

在我拥有的航空公司课程中(无法编辑或更改,这些是为我分配的头文件):

//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;
}

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

我现在遇到的问题是当我试图在我的阵列中的Flight中访问flightNum(或任何getter方法)时。我将数组的索引设置为指向我在add()方法中发送的航班的地址,但之后我无法访问它...

2 个答案:

答案 0 :(得分:2)

使用构造函数:

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数组的指针

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

void Airline::add(Flight* flight){
    if(size >= capacity){
        resize();
    }

    array[size] = flight;
    size++;
    cout << array[size]->getFlightNum(); 
}

在您打印航班号后,您在array[size]->getFlightNum();递增后正在执行size。交换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也会导致seg错误,并且代码中仍有更多错误。我会让你离开这里,因为它是家庭作业。

答案 1 :(得分:0)

听起来你正在编写超出数组范围的内容。我有一种感觉问题在这里:

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

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