سؤال

**** آسف على الارتباك فيما يتعلق Numcars في المشاركة الأصلية. قمت بتعديل التعليمات البرمجية لتكون متسقة مع الأصل ******

البرنامج الأكاديمي التالي هو إصدار مبسط للمشكلة الأصلية، لكنه يركز على المشكلة التي لم أكن بعد حلها بعد. هناك 2 فصول وطريقة رئيسية لهذه المشكلة، وتتألف الفصولتين من فئة تاجر وطبقة سيارة. تحتوي فئة الوكيل على سيارة خاصة * مؤشر تتم تهيئتها إلى صفيف ديناميكي في منشئ الوكيل. يحدث الخطأ في الطريقة الرئيسية عند استدعاء طريقة AddCar الخاصة بالمتاجر. في الطريقة الرئيسية، اجتياز متغير الوكيل عمدا إلى طريقة AddCar (Tealer & D) لتقليد هيكل التطبيق الأصلي. تستدعي طريقة AddCar هذه الطريقة التي تستثمر طريقة تاجر AddCar (Const Car & Car) حيث يحدث انتهاك الوصول عند تنفيذ السيارات [numcars ++] = السيارة؛ هل يمكنك شرح لماذا السيارات [numcars ++] = نتائج السيارة في انتهاك وصول

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

using namespace std;

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

: NUMCARS (0) {cars = سيارة جديدة [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) {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;
}
هل كانت مفيدة؟

المحلول

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

لا تهيئة NUMCARS - فهي تحتوي على بعض القيمة من كومة الكومة والتي هي بالتأكيد غير صفرية تقريبا. هذا يؤديك إلى القراءة بعد نهاية صفيف السيارات وفي الذاكرة التي لا يمكن الوصول إليها. يجب عليك تعيين numcars إلى 0 في منشئك.

علاوة على ذلك، يجب أن يكون لديك بعض الشيكات في AddCar بحيث لا تغادر صفيف السيارات.

تعديل:

هناك بعض المشكلات الأخرى التي تحتوي على الرمز - على سبيل المثال، "D = Tealer ()؛" ينشئ وكيل جديد وكتابة فوق المرء الذي تقوم به بالرجوع إلى Addcars التي لا يبدو أن ما تريد القيام به.

حاول إضافة بعض التتبع الإضافي إلى المنشئ / المدمرين للتحقق من أن المنشئين الذين تعتقدون أنهم يتم استدعاؤهم بالفعل - يبدو أن الوكيل () يجب استدعاء المنشئ بوسيطة افتراضية تحددها، ولكن إذا لم يكن الأمر كذلك هو الحصول على المنشئ الافتراضي وبعد

نصائح أخرى

أنت لا تهيئة numCars في أي مكان، يجب عليك تعيينه إلى 0:

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

هل لديك لاستخدام مؤشرات الخام؟ لماذا لا تلتفها واستخدامها std::vector في حين أن؟

لا شيء في التعليمات البرمجية أعلاه تهيئة الوكيل :: NUMCARS. لذلك يمكن أن يكون أي القمامة العشوائية.

ربما أنا لا أرى ذلك ولكن أين تحدد في البداية numcars؟

هذا يبدو وكأنه تسريب ذاكرة بالنسبة لي منذ ذلك الحين، لا تطلق الذاكرة السابقة التي عقدتها سيارات مؤشر:

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
}
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 ");
       }
    
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top