Frage

**** Sorry für die Verwirrung in Bezug auf numCars in der ursprünglichen Nachricht. Ich den Code geändert, um im Einklang mit dem ursprünglichen ******

Das folgende akademische Programm ist eine vereinfachte Version des ursprünglichen Problems, aber es konzentriert sich auf die Frage, die ich noch zu lösen. Es gibt zwei Klassen und eine Hauptmethode für dieses Problem und die 2 Klassen bestehen aus einer Händlerklasse und Auto-Klasse. Die Dealer-Klasse verfügt über einen eigenen Auto * Zeiger, der auf einen dynamischen Array in den Händlern Konstruktor initialisiert wird. Der Fehler tritt in der Hauptmethode, wenn der addCar Methode des Dealers aufgerufen wird. Im Haupt Methode übergeben I absichtlich den Dealer Variable auf den addCar (Händler & d) Verfahren, die die Struktur der ursprünglichen Anwendung zu simulieren. Die addCar Methode ruft dann die Händler addCar (const Car & Auto) Verfahren, bei dem die Zugriffsverletzung tritt auf, wenn ich Autos auszuführen [numCars ++] = Auto; Können Sie erklären, warum Autos [numCars ++] = Auto führt zu einer Zugriffsverletzung

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

using namespace std;

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

: numCars (0) {Autos = 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;
}
War es hilfreich?

Lösung

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

Sie nie numCars initialisieren - es enthält einen Wert aus dem Haufen, die fast definitiv nicht Null ist. Dies bewirkt, dass man sich über das Ende des Autos Array und in unzugänglichen Speicher zu lesen. Sie sollten numCars auf 0 in Ihrem Konstruktor festgelegt.

Am Anfang dieser, sollten Sie einige Kontrollen in addCar haben, so dass Sie nicht die Autos Array überrannt haben.

EDIT:

Es gibt einige andere Probleme mit dem Code - zum Beispiel "d = Dealer ();" erstellt einen neuen Händler und überschreibt die, die Sie mit Bezug auf addCars passieren, die nicht zu sein scheint, was Sie tun wollen.

Versuchen Sie, einige zusätzliche Verfolgung an den Konstruktor Hinzufügen / Destruktoren, um zu überprüfen, dass der Konstrukteure Sie denken, genannt ist eigentlich werden - es scheint, dass Dealer () sollen den Konstruktor mit einem Standardargument seinen Aufruf Sie angegeben, aber wenn nicht wird es immer der Standardkonstruktor.

Andere Tipps

Sie sind nicht numCars überall initialisieren, sollten Sie es auf 0 gesetzt:

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

Haben Sie rohe Zeiger verwenden? Warum es nicht einpacken und verwendet std::vector statt?

Nichts in dem obigen Code initialisiert Händler :: numCars. Es kann also jeder beliebiger Müll sein.

Vielleicht sehe ich es nicht, aber wo bekommt man anfänglich numCars?

Das sieht wie ein Speicherleck zu mir, da Sie nicht loslassen den vorherigen Speicher gehalten durch die Autos Zeiger:

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

und dieser Code sollte sollte wirklich Schutz vor dem Überlauf:

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

durch so etwas wie dies zu tun:

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

Ich sehe keine Probleme, die aus dem entsandten Code. sein Problem kann ist anderswo?

Wahrscheinlich können Sie versuchen, folgendermaßen vor:

  • Änderung Arrays Vektor und versucht, unter Verwendung von () out_of_range Ausnahme zu fangen. so etwas wie:

       std::vector<int> myVec;
       try
       {
        int x = myVec.at(0);
    
       }
       catch(std::out_of_range& oor)
       {
            printf("\nout of range ");
       }
    
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top