الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

خطأ في تنفيذ destructor

بدأه المـقـدام في 3 ديسمبر 2014 · 1 رد · 1,977 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

أحييكم بتحية الإسلام

السلام عليكم ورحمة الله وبركاته

 

في لحطات من كتابة الكود

تختفي ملامح البرمجة من البرنامج ليبقى مجردا من عوامل تعرية المنطق

 

كتبت برنامج لكن لم استوعب ترتيت destructor

 

ليس هناك خطأ في البرنامج صحيح ولكن :

#include <iostream>
#include <string.h>
using namespace std;

class first
{
char* a;
public:
first(){
a=NULL;
}
first(char* B)
{
a=new char[strlen(B)+1];
strcpy(a,B);
}
~first()
{
// delete[] a; //المشكلة عند إزالة التعليق
// يتنفذ البرنامج لكن عند الخروج
// تظهر رسالة debug assertion Failed 
// في مترجم فيجول سي بلس بلس
}
};

class second
{
first f;

public:
second(){}

second(first v)
{
f=v;
}
~second()
{

}
};

int main()
{
first s("Ahmed");
second f(s);
system("pause");
return 0;

تم تعديل هذه المشاركة بواسطة المـقـدام في 4 ديسمبر 2014 في 05:57

 إن المعلم والطبيب كلاهمــــا ... لا ينصحـان إذا همـا لم يكرمـا 


فاصبر لدائـك إن أهنت طبيبه ... واصبــر لجهلك إن جفوت معلما

#2

المشكلة لديك أن char* a مشتركة، عندما يستدعى الـdestructor فستحرر الذاكرة المحجوزة لـa، وتبقى الكائنات التي تشير لنفس الذاكرة تشير لبيانات غير صالحة.

 

أول destructor سيستدعى ويسبب المشكلة هنا (القيمة الممررة v):

  second(first v)  {    f=v;  }

في الدالة الرئيسية:

  first s("Ahmed");  second f(s);

مررت s بالقيمة، لذا سيستدعى الـcopy constructor التابع لـfirst، طالما أنك لم توفر واحد فسيوفر لك copy constructor افتراضي يستنسخ قيمة a (المؤشر)، الآن عندما تنتهي second فيستدعى الـdestructor الخاص بـv، وقتها أصبح الؤشر يشير لبيانات غير صالحة.

 

حلها يعتمد على فكرة برنامجك (ليست واضحة من الكود الذي وضعته)، لكنك تحتاج أن تنشئ copy constructor و assignment operator.

 

مثلاً هنا على فرض أنك تريد استنساخ a:

#include <iostream>
#include <cstring>
// #include <cstdlib>
using namespace std;

class first
{
  char* a;
public:

  first() {
    a=NULL; // NULL تذكر أنها قد تشير إلى
  }

  first(const char* B)
  {
    a = new char[strlen(B)+1];
    strcpy(a,B);
  }

  // copy constructor
  //
  // first a;
  // first b = a; < b copy constructor سيستدعى لأن الكائن لم ينشأ بعد
  //
  first(const first& f) {
    if(f.a != NULL) {
      a = new char[strlen(f.a)+1];
      strcpy(a, f.a);
    } else {
      a = NULL;
    }
  }

  // assignment operator
  //
  // first a;
  // first b;
  // b = a; < b assignment operator ستستدعى لأنه لدينا كان سبق إنشاءه
  //
  first& operator=(const first& f) {
    delete[] a; // مهم أن تتخلص من الذاكرة المحجوزة إن وجدت

    if(f.a != NULL) {
      a = new char[strlen(f.a)+1];
      strcpy(a, f.a);
    } else {
      a = NULL;
    }

    return *this;
  }

  ~first()
  {
    delete[] a;
  }
};

class second
{
  first f;

public:
  second(){}

  second(first v)
  {
    f=v;
  }

  ~second()
  {

  }
};

int main()
{
  first s("Ahmed");
  second f(s);
  //system("pause");
  return 0;
}
1

مواضيع مشابهة