Domanda

**** Ci scusiamo per la confusione per quanto riguarda numCars nel post originale. Ho modificato il codice per essere coerente con l'originale ******

Il seguente programma accademico è una versione semplificata del problema originale, ma si concentra sulla questione che devo ancora risolvere. Ci sono 2 classi e un metodo principale per questo problema e le 2 classi sono costituite da una classe Dealer e una classe Car. La classe Dealer ha un puntatore privata auto * che viene inizializzato a una matrice dinamica nel costruttore del rivenditore. L'errore si verifica nel metodo principale quando il metodo addCar del rivenditore viene richiamato. Nel metodo principale intenzionalmente passare la variabile rivenditore al addCar (rivenditore e d) metodo per imitare la struttura dell'applicazione originale. Il metodo addCar poi invoca addCar del banco (const Auto e auto) metodo in cui la violazione di accesso si verifica quando eseguo le auto [numCars ++] = auto; Può spiegare il motivo per cui le auto [numCars ++] = risultati di auto in una violazione di accesso

/**********************************Dealer.h**************************/
#include <cstdlib>
#include "Car.h"

using namespace std;

class Dealer
{
    public:
        Dealer(int maxCars = DEFAULT_MAX_CARS)

: numCars (0) {Auto = new Car [maxCars];}

        ~Dealer(){delete [] cars;}

        int getTotalCars() const { return numCars;}

        void addCar(const Car& car)
        {       
             cars[numCars++] = car; // Access Violation
        }

        Car* begin(){return cars;};

        Car* end(){ return cars + numCars;} 

setNumCars (int count) {numCars = count;}

    private:
        static const int DEFAULT_MAX_CARS = 10;
        Car* cars;
        int numCars;
};

/**********************************Car.h**********************/
#include <cstdlib>
#include <string>

using namespace std;


class Car{
    public:

        Car()
            : year(0), make(""), model("")
        {}

        Car(int year, string make, string model)
            : year(year), make(make), model(model)
        {}      

        string getMake() const {return make;}
        void setMake(string make){this->make=make;}

        string getModel() const {return model;}
        void setModel(string model){this->model=model;}

        int getYear() const {return year;}
        void setYear(int year){this->year=year;}

    private:
        int year;
        string make;
        string model;       
};


ostream& operator<< (ostream& out, const Car& car)
{
    out << car.getYear() << " " << car.getMake() << " " << car.getModel();
    return out;
}

/**********************************Main.cpp**********************/
#include &lt;cstdlib&gt;
#include &lt;iostream&gt;
#include "Dealer.h"

using namespace std;

void addCar(Dealer& d);

int main(int argc, char *argv[])
{
    Dealer d;

    addCar(d);  

    system("PAUSE");
    return EXIT_SUCCESS;
}

void addCar(Dealer& d)
{
    d = Dealer();

    d.addCar(Car(2007, "Honda", "Civic"));

    cout << d.getTotalCars() << " total cars" << endl;
}
È stato utile?

Soluzione

void addCar(const Car& car)
{
     cars[numCars++] = car; // Access Violation
}

Non si può mai inizializzate numCars - contiene un certo valore dal mucchio, che quasi sicuramente è diverso da zero. Questo fa sì che di leggere oltre la fine della matrice automobili e nella memoria inaccessibile. È necessario impostare numCars a 0 nel costruttore.

In cima a questo, si dovrebbe avere alcuni controlli in addCar modo che non invasa la matrice auto.

EDIT:

Ci sono alcuni altri problemi con il codice - per esempio, "d = Dealer ();" crea un nuovo concessionario e sovrascrive quello che si passa con riferimento al addCars che non sembra di essere ciò che si vuole fare.

Prova ad aggiungere un po 'di ulteriore analisi al costruttore / distruttori per verificare che i costruttori che ritengono di essere chiamato in realtà sono - sembra che Dealer () dovrebbe essere richiamando il costruttore con un argomento di default si è specificato, ma se non si sta facendo il costruttore di default.

Altri suggerimenti

Non sei l'inizializzazione numCars da nessuna parte, si dovrebbe impostare a 0:

Dealer(int maxCars = DEFAULT_MAX_CARS) :
numCars(0)
{
    cars = new Car[maxCars];
}

Dovete utilizzare i puntatori prime? Perché non avvolgetelo e utilizzare std::vector invece?

Niente nel codice sopra inizializza Dealer :: numCars. Si può quindi essere qualsiasi spazzatura casuale.

Forse non sto vedendo, ma da dove inizialmente impostato numCars?

Questo appare come un perdita di memoria per me da quando, non si rilascia la memoria precedente, tenutasi dal auto puntatore:

setNumCars(0) {cars = new Car[maxCars];}

e questo codice dovrebbe in realtà dovrebbe evitare la condizione di overflow:

void addCar(const Car& car)        
{                                
   cars[numCars++] = car; // Access Violation        '
}

facendo qualcosa di simile a questo:

void addCar(const Car& car)        
{                                
   if (numCars < maxCars)
      cars[numCars++] = car;        '
   else
      // throw and exception .....
      // or better still grow the cars buffer
}
cars[numCars++] = car; // Access Violation

Non vedo alcun problema dal codice pubblicato. Può essere problema è altrove?

Probabilmente si può provare seguenti:

  • array cambiare per vettore e provare a utilizzare in () per prendere out_of_range eccezione. qualcosa di simile:

       std::vector<int> myVec;
       try
       {
        int x = myVec.at(0);
    
       }
       catch(std::out_of_range& oor)
       {
            printf("\nout of range ");
       }
    
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top