2009-09-22 120 views
0

****對不起原始文章中有關numCars的混淆。我修改了代碼以與原始代碼保持一致C++動態數組訪問衝突

以下學術程序是原始問題的簡化版本,但它着重解決了我尚未解決的問題。這個問題有兩個類和一個主要方法,這兩個類由Dealer類和Car類組成。 Dealer類有一個私人Car *指針,它在Dealer的構造函數中被初始化爲一個動態數組。經銷商的addCar方法被調用時,主方法發生錯誤。 在主要方法中,我故意將Dealer變量傳遞給addCar(Dealer & d)方法來模擬原始應用程序的結構。 addCar方法然後調用經銷商的addCar(const Car & car)方法,當我執行cars [numCars ++] = car;你能解釋爲什麼汽車[numCars ++] =車導致訪問衝突

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

using namespace std; 

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

:numCars(0) {汽車=新車[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(詮釋計數) {numCars =計數;}

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
void addCar(const Car& car) 
{ 
    cars[numCars++] = car; // Access Violation 
} 

你永遠不會初始化numCars - 它包含這堆一定的價值幾乎肯定不是零。這會導致您讀取超出汽車陣列的尾部並進入無法訪問的內存。您應該在您的構造函數中將numCars設置爲0。

最重要的是,您應該在addCar中進行一些檢查,以便不超出汽車數組。

編輯:

沒有與代碼中的一些其他問題 - 例如, 「d =經銷商();」創建一個新的經銷商並覆蓋您通過引用傳遞給addCars的那個,這似乎不是您想要做的。

嘗試向構造函數/析構函數添加一些額外的跟蹤來驗證您認爲被調用的構造函數實際上是 - Dealer()應該使用您指定的默認參數調用構造函數,但如果不是獲取默認的構造函數。

+0

你以10秒打我:( – GManNickG 2009-09-22 01:15:42

+0

你是正確的關於不進行初始化numCars,但它是在原來的代碼初始化,我仍然得到訪問衝突錯誤,如果我改變汽車。 [numCars ++] = car to cars [0 | 1 | 2 | 3 | ...] = car; – 2009-09-22 01:16:39

+0

我修改了addCars的簽名,期望Dealer *避免創建經銷商的新實例,但並未解決Access違規錯誤addCar方法中的d的重新初始化對我來說也是可疑的,但改變它沒有效果 – 2009-09-22 01:54:41

1

你沒有初始化numCars的任何地方,你應該把它設置爲0:

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

你有使用原始指針?爲什麼不把它包起來並用std::vector代替?

+0

基於要求,我必須使用動態數組 – 2009-09-22 01:39:13

+0

這很不幸,你mi ght用矢量做任務,所有其他的工作都在工作,然後去掉矢量。 – GManNickG 2009-09-22 02:08:47

1

上述代碼中沒有任何內容初始化Dealer :: numCars。因此它可以是任何垃圾。

1

也許我沒有看到它,但你最初設置numCars在哪裏?

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 
} 
0
cars[numCars++] = car; // Access Violation 

我從發佈的代碼中看不到任何問題。可能是其他地方的問題?

也許你可以嘗試以下操作:

  • 改變陣列載體,嘗試使用在()來捕捉out_of_range例外。 類似:

    std::vector<int> myVec; 
        try 
        { 
        int x = myVec.at(0); 
    
        } 
        catch(std::out_of_range& oor) 
        { 
         printf("\nout of range "); 
        } 
    
+0

我必須使用數組,我同意它看起來應該可以工作。我一直在比較代碼動態數組的其他例子,我還沒有發現任何差異。 – 2009-09-22 02:27:46