خطأ: 'لا يمكن لـ GDB الوصول إلى الذاكرة في العنوان' في C++

Khta La Ymkn L Gdb Alwswl Aly Aldhakrt Fy Al Nwan Fy C



يعد تصحيح الأخطاء جزءًا أساسيًا من العملية عند تطوير التطبيقات بلغة C++ أو أي لغة برمجة أخرى. إنشاء التطبيقات بلغة C++ ليس بالأمر السهل؛ أنها تنطوي على مهارات جيدة في بنية البيانات، ومهارات إصلاح الأخطاء، وإدارة أدوات التصحيح. يعد GDB، GNU Debugger، أداة فعالة تساعد المطورين على تحديد الأخطاء الموجودة في التعليمات البرمجية الخاصة بهم وحلها. GDB هي أداة بسيطة ومفيدة بشكل مثير للاهتمام تساعد المطورين في العثور على أخطاء التعليمات البرمجية وإصلاحها.

ومع ذلك، أثناء استخدام GDB، قد تواجه الخطأ 'خطأ: يتعذر على GDB الوصول إلى الذاكرة في العنوان'. يمكن أن يكون هذا الخطأ مربكًا ويجعل من الصعب الاستمرار في تصحيح الأخطاء. تركز هذه المقالة على تحديد سبب حدوث هذا الخطأ والنظر في بعض أمثلة التعليمات البرمجية التي تساعدنا على فهم كيفية حل هذا الخطأ.

مثال 1:

دعونا نرى أول مثال للتعليمات البرمجية لدينا والذي، عند التنفيذ، يعطي خطأ 'لا يمكن لـ GDB الوصول إلى الذاكرة في العنوان'. أولاً، ننظر إلى الكود. وبعد ذلك سنرى شرح ذلك سطرًا بسطر.







#تشمل
استخدام مساحة الاسم الأمراض المنقولة جنسيا ;
كثافة العمليات رئيسي ( فارغ ) {
كثافة العمليات * ص ;
cout << * ص ;
}

يبدأ البرنامج بإعلان توجيهات المعالج المسبق '#include ' واستخدام 'مساحة الاسم std' التي تعتبر ضرورية ليتم تضمينها في البرنامج لاستخدام وظائف الإدخال والإخراج القياسية. بعد ذلك تأتي نقطة الدخول الرئيسية وهي “int main(void);”. يعلن هذا السطر نقطة بداية البرنامج.



ضمن الوظيفة الرئيسية، يتم الإعلان عن متغير المؤشر '*p'. هنا، لم تتم تهيئة المتغير 'p'. ومن ثم، فإنه لا يشير إلى أي موقع ذاكرة محدد محجوز للعدد الصحيح. يتسبب هذا السطر في حدوث خطأ سنقوم بحله لاحقًا. في السطر التالي، نحاول طباعة قيمة المتغير '*p' باستخدام عبارة 'cout'.



نظرًا لأن المتغير 'p' هو مؤشر من النوع الصحيح، يتم استخدام العلامة النجمية '*' لإلغاء الإشارة إليه. وهذا يعني أن القيمة موجودة في موقع الذاكرة الذي تشير إليه. ومع ذلك، نظرًا لعدم تهيئة المؤشر 'p' ولا يشير إلى أي موقع محدد وصالح، فإن إلغاء الإشارة إلى المؤشر سيؤدي إلى سلوك غير محدد. وبالتالي، فإنه يؤدي إلى توليد أنواع مختلفة من الأخطاء اعتمادا على النظام والمترجم. نظرًا لأننا نستخدم مترجم GDB لتصحيح أخطاء هذا البرنامج وتشغيله، فسيقوم مصحح الأخطاء بإلقاء الخطأ التالي. يظهر الخطأ في مقتطف الإخراج:





كما ترون في الإخراج، لا يستطيع مصحح الأخطاء الوصول إلى الذاكرة. يقوم هذا البرنامج بإلغاء الإشارة إلى مؤشر غير مهيأ، وهو السبب الرئيسي لهذا السلوك غير المحدد. والآن، دعونا نرى كيف يمكننا حل هذه المشكلة. ويرد الرمز الصحيح في ما يلي. ألقِ نظرة عليه وسنشرح لك كيفية إصلاح الخلل في الكود:



#تشمل
استخدام مساحة الاسم الأمراض المنقولة جنسيا ;
كثافة العمليات رئيسي ( فارغ ) {
كثافة العمليات فال = 5 ;
كثافة العمليات * ص = & فال ;
cout << 'القيمة هي =' << * ص ;

}

كما ترون، تم تعديل الكود من خلال تضمين 'int val =5;' إفادة. يعلن هذا السطر عن متغير عدد صحيح يسمى 'val' ويقوم بتهيئته بقيمة '5'. يعلن السطر التالي، 'int *p = &val;'، عن متغير مؤشر '*p' ويتم تهيئته للإشارة إلى عنوان المتغير 'val'. في السابق، لم يكن المؤشر '*p' يشير إلى أي عنوان ذاكرة مما تسبب في 'تعذر الوصول إلى الذاكرة عند العنوان 0x0'.

لحل هذه المشكلة، تم الإعلان عن المتغير 'var' وتهيئته وتخصيصه للمؤشر '*p'. الآن، يشير المؤشر '*p' إلى عنوان المتغير 'val' حيث يأخذ عامل التشغيل '&' عنوان 'val' ويعينه إلى 'p'. مرة أخرى، يتم استخدام عبارة 'cout' لطباعة قيمة المؤشر '*p'. راجع مقتطف الإخراج التالي لمعرفة قيمة 'val' التي يتم الوصول إليها بواسطة المؤشر '*p':

كما ترون، تم حل الخطأ وتهيئة القيمة '5' منذ طباعة المتغير 'val' عن طريق استدعاء المؤشر '*p' valribale.

مثال 2:

دعونا نفكر في مثال آخر يشرح كيفية التعامل مع الخطأ 'لا يمكن لـ GDB الوصول إلى الذاكرة في العنوان' في برنامج التعليمات البرمجية C++. ويرد الرمز في ما يلي للرجوع إليها. الق نظرة:

#تشمل
كثافة العمليات رئيسي ( ) {
كثافة العمليات * ص = جديد كثافة العمليات [ خمسة عشر ] ;
يمسح [ ] ص ;
الأمراض المنقولة جنسيا :: cout << ص [ 2 ] << الأمراض المنقولة جنسيا :: endl ;
يعود 0 ;
}

أحد السيناريوهات الأكثر شيوعًا التي يواجهها المطورون أثناء البرمجة باستخدام المؤشرات هو تخصيص الذاكرة بشكل غير صحيح أو غير مناسب. ينتج عن GDB الخطأ عند حدوث تخصيص غير صحيح للذاكرة وإلغاء التخصيص في برنامج C++.

بالنظر إلى مثال التعليمات البرمجية السابق، تتم تهيئة المؤشر '*p' باستخدام int[15] جديد. يخصص هذا البيان ديناميكيًا مصفوفة مكونة من 15 عددًا صحيحًا باستخدام عامل التشغيل الجديد. يقوم متغير المؤشر '*p' بتخزين عنوان ذاكرة المصفوفة.

في العبارة التالية، 'delete[] p;،' يشير إلى أنه تم إلغاء تخصيص الذاكرة باستخدام أمر الحذف[]. يقوم أمر الحذف [] بإلغاء تخصيص الذاكرة المخصصة مسبقًا للمؤشر '*p' مما يعني أن استخدامات النظام الأخرى يمكنها تخصيص كتلة الذاكرة المخصصة مسبقًا مرة أخرى. عندما نحاول طباعة قيمة المتغير '*p' باستخدام عبارة 'cout'، سنحصل على خطأ الوصول إلى الذاكرة كما هو موضح في المخرجات التالية:

الأشياء التي يجب وضعها في الاعتبار هنا هي أن رسالة الخطأ الدقيقة قد تختلف قليلاً اعتمادًا على إصدار ونظام GDB لديك. لكن 'الخطأ: يتعذر على GDB الوصول إلى الذاكرة في الموقع' والخطأ المحدد في المقتطف السابق متماثلان. لحل هذا الخطأ، نقوم ببساطة بتغيير أمر الحذف [] بعد عبارة 'cout'. انظر الكود المعدل فيما يلي:

#تشمل
كثافة العمليات رئيسي ( ) {
كثافة العمليات * ص = جديد كثافة العمليات [ خمسة عشر ] ;
ل ( كثافة العمليات أنا = 0 ; أنا < خمسة عشر ; ++ أنا ) {
ص [ أنا ] = أنا * 2 - 5 + 8 ;
الأمراض المنقولة جنسيا :: cout << 'ص[' << أنا << '] = ' << ص [ أنا ] << الأمراض المنقولة جنسيا :: endl ;
}
يمسح [ ] ص ;
يعود 0 ;
}

هنا، يمكنك أن ترى أننا قمنا بتهيئة المصفوفة بالقيم التي تم حسابها في وقت التشغيل، وقمنا بطباعة جميع قيم الحلقة باستخدام حلقة 'for'. أهم شيء يجب ملاحظته هنا هو تغيير عبارة الحذف[]؛ يتم استدعاؤه الآن بعد الحصول على كافة قيم المصفوفة التي أزالت خطأ الوصول إلى الذاكرة. انظر الإخراج النهائي للكود في ما يلي:

خاتمة

في الختام، يشير الخطأ 'خطأ: يتعذر على GDB الوصول إلى الذاكرة في العنوان' عادةً إلى مشكلات متعلقة بالذاكرة في كود C++. استكشفت هذه المقالة بعض السيناريوهات الشائعة التي تؤدي إلى ظهور هذا الخطأ لتوضيح متى وكيف يمكن حله. عندما يحدث هذا الخطأ في التعليمات البرمجية، فمن الضروري مراجعته بعناية من خلال إيلاء اهتمام وثيق لمتغيرات المؤشر وتخصيصات الذاكرة والمصفوفات والهياكل.

علاوة على ذلك، يمكن لميزات مثل نقاط التوقف التي يوفرها GDB أن تساعد في تحديد موقع الخطأ أثناء تصحيح أخطاء البرنامج. يمكن أن تساعد هذه الميزات في تحديد الموقع الدقيق للأخطاء المتعلقة بالذاكرة. ومن خلال معالجة هذه المشكلات بشكل استباقي، يمكن للمطورين تحسين استقرار وموثوقية تطبيقات C++ الخاصة بهم.