كيفية اكتشاف تسرب الذاكرة في C/C++ باستخدام Valgrind

Kyfyt Aktshaf Tsrb Aldhakrt Fy C C Bastkhdam Valgrind



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

عندما تقوم بتشغيل برنامج ضمن Valgrind، فإنه يتحكم ديناميكيًا في الملف القابل للتنفيذ الخاص بالبرنامج، مما يسمح له بمراقبة استخدام ذاكرة البرنامج وسلوك التنفيذ.

تسرب الذاكرة في C++

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







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



تثبيت فالغريد

لتثبيت Valgrind على نظام Linux، افتح محطة طرفية وقم بتحديث مستودعات الحزم الخاصة بك باستخدام مدير الحزم الخاص بتوزيع Linux الخاص بك. يعمل الأمر التالي مع الأنظمة المستندة إلى Ubuntu وDebian:



$ sudo تحديث مناسب

استخدم مدير الحزم لتثبيت Valgrind. مرة أخرى، قد يختلف الأمر وفقًا لتوزيع Linux لديك. استخدم الأمر التالي للأنظمة المستندة إلى Ubuntu وDebian:





$ sudo ملائم ثَبَّتَ بوابة الانتخابات

عند المطالبة، أدخل كلمة مرور المستخدم الخاصة بك واضغط على 'أدخل'. لاحظ أن حساب المستخدم الخاص بك يحتاج إلى امتيازات إدارية لتثبيت البرنامج. يقوم مدير الحزم بتنزيل Valgrind وتثبيته مع أي تبعيات ضرورية. قد تستغرق العملية بضع دقائق.



بعد الانتهاء من عملية التثبيت، يمكنك تأكيد التثبيت الناجح لبرنامج Valgrind عن طريق تنفيذ الأمر التالي كخطوة تحقق:

$ بوابة الانتخابات --إصدار

يعرض هذا الأمر معلومات إصدار Valgrind إذا تم تثبيته بنجاح.

هذا كل شيء! يجب الآن تثبيت Valgrind على نظام Linux الخاص بك، ويمكنك استخدامه لتحليل وتصحيح برامج C/C++ الخاصة بك بحثًا عن تسرب الذاكرة والمشكلات الأخرى.

إنشاء ملف في أوبونتو

لبدء العمل على البرنامج، نحتاج أولاً إلى إنشاء ملف في Ubuntu. لإنشاء الملف، نستخدم محرر النصوص nano. لذلك نكتب الأمر على الطرفية كما يلي:

$ نانو file1

هنا، nano هو اسم محرر النصوص الذي يتم تنفيذه. تمثل الوسيطة 'file1' اسم الملف الذي تنوي فتحه أو إنشائه باستخدام محرر النصوص nano. يفتح Nano الملف للتحرير إذا كان موجودًا بالفعل؛ إذا لم يكن الأمر كذلك، فإنه يقوم بإنشاء ملف جديد بالاسم المقدم. نظرًا لعدم وجود مثل هذا الملف لدينا، فإنه يقوم بإنشاء مستند جديد باسم 'file1'.

بمجرد تشغيل الأمر، سيتم فتح محرر nano، مما يوفر لك لوحة فارغة لإدخال محتوى الملف 'file1' أو تحريره. يمكنك البدء في كتابة المحتوى الموجود أو لصقه في المحرر.

الآن بعد أن تم تحقيق كافة المتطلبات الأساسية، قمنا بإنشاء بعض الأمثلة لاستخدام Valgrind لاكتشاف تسرب الذاكرة في برامج C++.

مثال 1:

المثال الأول الذي نقدمه يوضح مثالًا بسيطًا لتخصيص الذاكرة الديناميكية باستخدام الدالة 'malloc' من مكتبة في لغة C.

#تشمل

كثافة العمليات رئيسي ( )

{

شار * أ = malloc ( 102 ) ;

يعود 0 ;

}

إليك تفاصيل الكود:

نقوم أولاً بتضمين ملف رأس المكتبة القياسي الذي يوفر وظائف مثل malloc لتخصيص الذاكرة الديناميكية وإلغاء التخصيص.

يعلن سطر int main() عن الوظيفة الرئيسية. ثم، char *a = malloc(102); يعلن عن متغير المؤشر 'a' من النوع char* (مؤشر إلى char). ويستخدم وظيفة 'malloc' لتخصيص الذاكرة ديناميكيًا لمجموعة مكونة من 102 عنصر حرف (إجمالي 102 بايت). يتم إرسال حجم تخصيص الذاكرة، المعبر عنه بالبايت، كمدخل إلى وظيفة malloc ويقوم بإخراج مؤشر إلى كتلة الذاكرة التي تم إنشاؤها حديثًا. يتم تعيين قيمة المؤشر للمؤشر char* 'a'. وأخيرا، 'العودة 0؛' يدل على نهاية الوظيفة الرئيسية.

باختصار، يقوم هذا الكود بتخصيص الذاكرة ديناميكيًا لمجموعة مكونة من 102 عنصر حرف باستخدام 'malloc' ويعين عنوان الذاكرة للمؤشر 'a'. ومع ذلك، لاحظ أن الكود لا يستخدم أو يعالج الذاكرة المخصصة بأي شكل من الأشكال ولا يتضمن إلغاء تخصيص الذاكرة باستخدام مجاني.

عندما نقوم بتشغيل هذا البرنامج من خلال Valgrind مع خيار '–leak-check=full'، فإنه يقوم بإجراء فحص تسرب الذاكرة ويوفر تقرير الإخراج.

يتم تقديم تقرير الإخراج الذي تنتجه Valgrid على النحو التالي:

مثال 2:

للبدء بهذا الرسم التوضيحي، نقوم أولاً بإنشاء ملف 'test2' باستخدام محرر النصوص nano كما شرحنا سابقًا عن طريق كتابة الأمر:

$ نانو test2

الآن، نكتب برنامج C++ للتحقق من وجود أي تسرب للذاكرة باستخدام Valgrind:

#تشمل

#تشمل

#تشمل

ثابت كثافةت a_s = 3000 ;

انت مين ( ) {

كثافة العمليات * ia = malloc ( حجم ( كثافة العمليات ) * مثل ) ;

ل ( إنت ط = 0 ; أنا < مثل؛ أنا++ ) {

هو - هي [ أنا ] = أنا؛

}

رند ( وقت ( باطل ) ) ;

int rn = راند ( ) % مثل؛

printf ( 'إنه [%d]: %d ' ، آر إن [ آر إن ] ) ;

يعود 0 ;

}

دعونا نتعرف على البرنامج.

يتضمن الكود ملفات الرأس الضرورية ويحدد المتغير الثابت 'a_s' بقيمة 3000. داخل الدالة main()، يتم الإعلان عن مؤشر 'ia' من النوع int* ويتم تخصيص الذاكرة ديناميكيًا باستخدام 'malloc' وظيفة. يحدد التعبير 'sizeof(int) * a_s' إجمالي الذاكرة المطلوبة لتخزين عدد 'a_s' من الأعداد الصحيحة. تتم تهيئة جميع عناصر المصفوفة 'ia' بواسطة حلقة 'for' بقيمة الفهرس المقابلة لها. على سبيل المثال، ia[0] سيكون 0، ia[1] سيكون 1، وهكذا.

يتم إنشاء مولد الأرقام العشوائية باستخدام وظيفة 'srand' باستخدام الوقت الحالي. وهذا يضمن أن البرنامج ينتج مجموعة فريدة من الأعداد الصحيحة العشوائية في كل مرة يتم تنفيذها. تولد الدالة 'rand' رقمًا عشوائيًا، ويتم تعيين 'rn' بنتيجة rand() % a_s. يحد عامل المعامل '%' من نطاق الرقم العشوائي ليكون بين 0 وa_s - 1 والذي يتوافق مع فهرس صالح داخل الصفيف 'ia'.

وأخيرًا، يستخدم البرنامج وظيفة 'printf' لطباعة القيمة عند الفهرس 'rn' المختار عشوائيًا للمصفوفة 'ia'، إلى جانب الفهرس المقابل.

عند تشغيل هذا البرنامج من خلال Valgrind، فإنه يقوم بإنشاء تقرير الإخراج التالي:

  لقطة شاشة لوصف برنامج كمبيوتر تم إنشاؤه تلقائيًا

خاتمة

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