Question

**** Désolé pour la confusion en ce qui concerne numCars dans le message original. J'ai modifié le code pour être conforme à l'original ******

Le programme d'études suivant est une version simplifiée du problème d'origine, mais il se concentre sur la question que je n'ai pas encore à résoudre. Il y a 2 classes et une méthode principale de ce problème et les 2 classes se composent d'une classe de concessionnaires et une classe de voitures. La classe Dealer a un pointeur privé * voiture qui est initialisé à un tableau dynamique dans le constructeur du revendeur. L'erreur se produit dans la principale méthode est appelée lorsque la méthode de addCar du donneur. Dans le procédé principal, je passe intentionnellement la variable du courtier à la méthode addCar (concessionnaire et d) pour imiter la structure de la demande initiale. La méthode addCar invoque alors la méthode de addCar du concessionnaire (const voiture et voiture) où la violation d'accès se produit lorsque j'exécute les voitures [numCars ++] = voiture; Pouvez-vous expliquer pourquoi les voitures [numCars ++] = résultats de voiture dans une violation d'accès

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

using namespace std;

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

: numCars (0) {Voitures = new voiture [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;
}
Était-ce utile?

La solution

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

Vous n'initialisez numCars - il contient une valeur du tas qui est presque certainement non nulle. Cela vous amène à lire au-delà de la fin du tableau de voitures et dans la mémoire inaccessible. Vous devez définir numCars à 0 dans votre constructeur.

En plus de cela, vous devriez avoir quelques vérifications dans addCar afin que vous ne pas envahie le tableau voitures.

EDIT:

Il y a quelques autres problèmes avec le code - par exemple, "d = Dealer ();" crée un nouveau revendeur et celui que vous écrase passez par référence à addCars qui ne semble pas être ce que vous voulez faire.

Essayez d'ajouter une traçabilité supplémentaire au constructeur / Destructeurs pour vérifier que les constructeurs que vous pensez sont appelés sont en fait - il semble que le concessionnaire () doit être Invoquer le constructeur avec un argument par défaut que vous avez spécifié, mais sinon il devient le constructeur par défaut.

Autres conseils

Vous n'êtes pas initialiser numCars partout, vous devez le mettre à 0:

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

Avez-vous d'utiliser des pointeurs premières? Pourquoi ne pas l'envelopper et utiliser std::vector à la place?

Rien dans le code ci-dessus :: numCars Dealer initialise. Il peut donc être une poubelle au hasard.

Peut-être que je ne le vois pas, mais où est-ce que vous numCars initialement fixé?

Cela ressemble à une fuite de mémoire pour moi puisque, vous ne relâchez pas la mémoire précédente tenue par le voitures pointeur:

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

et ce code devrait devrait vraiment se prémunir contre la condition de débordement:

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

en faisant quelque chose comme ceci:

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

Je ne vois pas de problème à partir du code affiché. Peut être problème est ailleurs?

vous pouvez probablement essayer suivant:

  • changement des tableaux à vecteur et essayer d'utiliser au () pour attraper out_of_range exception. quelque chose comme:

       std::vector<int> myVec;
       try
       {
        int x = myVec.at(0);
    
       }
       catch(std::out_of_range& oor)
       {
            printf("\nout of range ");
       }
    
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top