0

**** 元の投稿の numCars に関する混乱について申し訳ありません。元の********と一致するようにコードを変更しました

次のアカデミック プログラムは、元の問題を簡略化したものですが、私がまだ解決していない問題に焦点を当てています。この問題には 2 つのクラスと main メソッドがあり、2 つのクラスは Dealer クラスと Car クラスで構成されます。Dealer クラスには、Dealer のコンストラクターで動的配列に初期化されるプライベート Car* ポインターがあります。ディーラーの addCar メソッドが呼び出されると、メイン メソッドでエラーが発生します。main メソッドでは、意図的に Dealer 変数を addCar(Dealer& d) メソッドに渡して、元のアプリケーションの構造を模倣しています。次に addCar メソッドは、cars[numCars++]=car; を実行するとアクセス違反が発生するディーラーの addCar(const Car& car) メソッドを呼び出します。cars[numCars++]=car がアクセス違反になる理由を説明できますか

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

using namespace std;

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

:numCars(0) {cars = 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;
}
4

6 に答える 6

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

numCars を初期化することはありません。ほぼ間違いなくゼロ以外のヒープからの値が含まれています。これにより、cars 配列の末尾を超えて、アクセスできないメモリに読み込まれます。コンストラクターで numCars を 0 に設定する必要があります。

これに加えて、cars 配列をオーバーランしないように、addCar でいくつかのチェックを行う必要があります。

編集:

コードには他にも問題があります - たとえば、「d = Dealer();」新しいディーラーを作成し、 addCars への参照によって渡すものを上書きしますが、これはあなたがやりたいことではないようです。

コンストラクター/デストラクタに追加のトレースを追加して、呼び出されていると思われるコンストラクターが実際に呼び出されていることを確認してみてください。 .

于 2009-09-22T01:13:19.307 に答える
1

numCarsどこも初期化していません。0 に設定する必要があります。

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

生のポインターを使用する必要がありますか? ラップしてstd::vector代わりに使用してみませんか?

于 2009-09-22T01:14:26.840 に答える
1

上記のコードでは、Dealer::numCars を初期化するものは何もありません。したがって、ランダムなガベージである可能性があります。

于 2009-09-22T01:14:43.000 に答える
1

見ていないかもしれませんが、最初に numCars をどこに設定しますか?

于 2009-09-22T01:15:57.163 に答える
0

のポインターが保持していた以前のメモリを解放しないため、これはメモリリークのように見えます。

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

そして、このコードは実際にはオーバーフロー状態を防ぐ必要があります:

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

このようなことをすることによって:

void addCar(const Car& car)        
{                                
   if (numCars < maxCars)
      cars[numCars++] = car;        '
   else
      // throw and exception .....
      // or better still grow the cars buffer
}
于 2009-09-22T01:30:08.207 に答える
0
cars[numCars++] = car; // Access Violation

投稿されたコードに問題はありません。問題は他の場所にあるのでしょうか?

おそらく、次のことを試すことができます。

  • 配列をベクトルに変更し、at() を使用して out_of_range 例外をキャッチしてみてください。何かのようなもの:

       std::vector<int> myVec;
       try
       {
        int x = myVec.at(0);
    
       }
       catch(std::out_of_range& oor)
       {
            printf("\nout of range ");
       }
    
于 2009-09-22T02:18:43.103 に答える