代码之家  ›  专栏  ›  技术社区  ›  Athens Holloway

C++动态数组访问违例

  •  0
  • Athens Holloway  · 技术社区  · 15 年前

    ****对于原邮件中有关numcars的混淆,我们深表歉意。我修改了代码使其与原始代码一致******

    下面的学术课程是原始问题的简化版本,但它关注的是我尚未解决的问题。这个问题有两个类和一个主要方法,这两个类由一个经销商类和一个汽车类组成。dealer类有一个private car*指针,该指针初始化为dealer构造函数中的动态数组。当调用经销商的addcar方法时,主方法中会发生错误。 在主方法中,我有意将dealer变量传递给addcar(dealer&d)方法,以模拟原始应用程序的结构。然后,addcar方法调用经销商的addcar(const car&car)方法,当我执行car s[numcars++]=car;时,会发生访问冲突。您能解释为什么car s[numcars+++]=car会导致访问冲突吗?

    /**********************************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(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;
    }
    
    6 回复  |  直到 15 年前
        1
  •  4
  •   Michael    15 年前
    void addCar(const Car& car)
    {
         cars[numCars++] = car; // Access Violation
    }
    

    您永远不会初始化numcars——它包含堆中的一些值,几乎肯定是非零的。这会导致您在cars数组的末尾读取数据,并进入不可访问的内存中。您应该在构造函数中将numcars设置为0。

    除此之外,您应该在addcar中有一些支票,这样您就不会超过cars数组。

    编辑:

    代码还有其他一些问题,例如,“d=dealer();”创建了一个新的经销商,并覆盖了您引用addcars传递的经销商,而addcars似乎不是您想要做的。

    尝试向构造函数/析构函数添加一些额外的跟踪,以验证您认为被调用的构造函数实际上是-看起来dealer()应该使用您指定的默认参数调用构造函数,但如果不是这样,它将获取默认的构造函数。

        2
  •  1
  •   GManNickG    15 年前

    您没有初始化 numCars 在任何地方,都应将其设置为0:

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

    你必须使用原始指针吗?为什么不把它包起来用呢 std::vector 相反?

        3
  •  1
  •   Geerad    15 年前

    以上代码中的任何内容都不会初始化dealer::numcars。因此,它可以是任何随机的垃圾。

        4
  •  1
  •   phoebus    15 年前

    也许我没看到,但你最初是在哪里设置numcars的?

        5
  •  0
  •   jussij    15 年前

    这看起来像 内存泄漏 对我来说,从那以后,你不会释放以前的记忆 汽车 指针:

    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
    }
    
        6
  •  0
  •   aJ.    15 年前
    cars[numCars++] = car; // Access Violation
    

    我看不到来自已发布代码的任何问题。问题可能出在别处?

    您可能可以尝试以下操作:

    • 将数组改为vector,并尝试使用at()来捕获范围异常。 类似:

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