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

( شبه لغز ): استخرج الخطأ القاتل في هذا الكود.

بدأه Abdullah.Alshammeri في 23 فبراير 2009 · 7 رد · 1,372 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

سأجرب كتابة ألغاز ايضا :lol:

- في الكود التالي خطأ منطقي ( أو بمعنى آخر , خطأ سيحصل أثناء وقت التشغيل , وفي حالة معيّنة وحيدة ( تقريبا) ) .. أي أنه لا يوجد خطأ في الصيغة syntax

المطلوب :

1- ماهو السطر الذي قد يسبب في تفجير هذا الخطأ أثناء التشغيل .. تحت ظرف معيّن .

2- ماهو العلاج الذي يزيل هذه المشكلة.

#include <iostream>
using namespace std;

	class Object
	{
	public:
		char *name;
		Object (char *name)
		{

			if (name == NULL)
				this->name = NULL;
			else
			{
				this->name = new char[strlen(name) + 1];
				strcpy (this->name, name);
			}
		}
		~Object ()
		{
			if (name != NULL)
				delete name;			 
		}
		Object & operator=(const Object & copy)
		{
			if(copy.name == NULL)
			{
				this->name = "NULL"; // or whatever (it does not matter)
				return *this;	
			}

			if (this->name != NULL)
			{
				delete this->name;
				this->name = NULL;
			}

		   this->name = new char[strlen (copy.name) + 1];
		   strcpy (this->name, copy.name);

			return *this;
		}


};


int main()
{

	Object object_1("object 1");
	Object object_2("object 2");

	object_1 = object_2;

	cout << " object_1 name: " << object_1.name << endl;


	return 0;
}

ارشاد :

- الكود السابق لا يوضّح الخطأ , ولايقوم بكشفه

- لكن بتغيير بسيط .. في الدالة main .. سينكشف الخطأ .. وهو خاص بالذاكرة ومشاكلها .. ماباقي الا أقول الحل .. :)

توضيح :

- هناك موضوع طويل .. يقف وراء هذا السؤال .. سأذكره بعد الحل ان شاء الله .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#2

تقريبا المشكله تحصل في حال أسندنا الكائن لنفسه ..

object1 = object1

حل المشكله هو بوضع جمله تحقق في الداله = تقوم بارجاع نسخه من نفس الكائن في حال كان المعامل المرسل هو نفس الكائن ..

if ( this == &copy)
	return *this; // or copy

بالتوفيق :) .

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#3

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

عندما نسند قيمة

بهذا الشكل

	 Object object_2;
	 Object object_1;
	 object_2 ="aaa";
	 object_1 ="bb";

سيظهر لنا خطأ لاننا لم نعرف باني الفئة ولم نهيئ قيمة name

tvquran_6.gif

#4

ربما ليس خطأ واحد ،، عموما اليك ما توصلت له :

اذا قمنا بالتالي :

Object object_1("object 1");
Object object_2(NULL);

بعد تطبيق الـAssignment سيكون لدينا :

Object object_1.name = "NULL"

الآن لدينا مشكلتين :

1- لقد فقدنا مؤشر Object object_1.name الى الأبد ولن نتمكن من تحرير الذاكرة الخاصة به !

2- عند استدعاء الـDestructor حيث سيقوم بتنفيذ الكود التالي :

delete name;

طبعا name في هذه الحالة لا تشير الى dynamic array بل الى عنوان ثابت في احد اقسام البرنامج وهو "NULL" .

------------------

لإصلاح الخطأ :

if(copy.name == NULL)
{
	if (this->name != NULL)
		delete this->name;
	this->name = new char[strlen("NULL") + 1];
	strcpy (this->name, "NULL"); // or whatever (it does not matter)
	return *this;
}

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#5

السلام عليكم ,,

هنا الخطأ الآخر الذي اكتشفته :D :

if (name != NULL)
 delete[] name;

و

delete[] this->name;

أشم رائحة خطأ آخر, أعتقد أنك تحاول حذف "NULL" في حالة من الحالات و التي هي أصلاً String Litral و لكني دعني أفحصها قليلاً بعد

---------------------------------------------------------------

لم أر مشاركة الأخ GM :) لذلك السطر الآخير في ردي لا لزوم له :)

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 23 فبراير 2009 في 21:12

#6

ماهذا .. من أين ظهرت هذه الاخطاء :D .

@ وجدي :

أصبت كبد المشكلة :) , هذه هي المشكلة المقصودة , وهذا هو الحل المطلوب .. عيني عليك باردة .

@ الشلوي :

ماذكرته يؤدّي إلى خطأ أثناء الترجمة , للسبب الذي ذكرت في رّدك , والمطلوب هو خطأ أثناء التشغيل , شكرا لمشاركتك :) .

@GamingMaster :

حاولت أني أحاصر الاعضاء في زاوية ضيقة ( ليبقى خطأ وحيد ) لذلك وضعت هذا الشرط

if(copy.name == NULL)
			{
				this->name = "NULL"; // or whatever (it does not matter)
				return *this;	
			}

ويبدو أني وقعت في خطأ آخر , شكرا لملاحظتك .. الصحيحة طبعا :) .

@ خالد :

هذا خطأ لا يغتفر .. وملاحظتك صحيحة طبعا .. لم انتبه له هو الاخر , لست مبرمجا سيئا لهذه الدرجة :D .. ولكن الكود ليس أنا من كتبه .. وأتحمّل الخطأ على كل حال :D .

نأتي للتوضيح والغاية من كتابة هذا الموضوع :

الكود في الأصل , مستخرج من هذا الموضوع

Why I Dislike C++ For Large Projects

في هذا الموضوع , يتحدّث الكاتب عن كرهه الدفين للغة السي بلس , وسرد جزء من معاناته ,

ولكن بعد كم الاخطاء الذي ارتكبها " كاتب الموضوع " .. وأكملت أنا الباقي ...

يبدو أن المشكلة في كاتب الموضوع .. وليس في لغة ++C .. ما رأيكم :D

تم تعديل هذه المشاركة بواسطة الشمري في 23 فبراير 2009 في 22:06

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#7

لهذا في المناطق الحساسة (ككود يعمل بمستوى النظام) لا استخدم OOP أبداً :P

الآن خالد سيقتلني :D

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#8

الأخ وجدي من أفضل الأصدقاء الذين رأيتهم اطلاعاً في برمجة الكائنات :)

اقتباس
لهذا في المناطق الحساسة (ككود يعمل بمستوى النظام) لا استخدم OOP أبداً

الآن خالد سيقتلني

أنا ضد البرمجة الكائنية في غير مكانها :wink:

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