2009-09-22 121 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