تخصيص الذاكرة الديناميكي في C ++

Tkhsys Aldhakrt Aldynamyky Fy C



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

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

اختلاف تخصيص الذاكرة للمتغيرات العادية

في المتغيرات العادية ، يتم تخصيص الذاكرة التي تم تخصيصها بواسطة مترجم وإلغاء تخصيصها تلقائيًا. عندما يتم تخصيص الذاكرة ديناميكيًا بواسطة المبرمج ، فإنه يتعين عليه بعد ذلك إزالة الذاكرة أو إلغاء تخصيصها عندما لا تكون ذات فائدة في التنفيذ الإضافي للكود المصدر. يتسبب هذا الموقف في 'تسرب للذاكرة' عند إنهاء البرنامج بينما لا يتم إلغاء تخصيص الذاكرة.







عوامل التشغيل للتخصيص الديناميكي

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



مشغل جديد

يشير إلى الطلب على تخصيص الذاكرة. يقوم المشغل الجديد بتهيئة الذاكرة وإرجاع عنوان تلك الذاكرة المخصصة إلى متغير المؤشر إذا كانت هناك ذاكرة متوفرة كافية.



كائن المؤشر = الجديد بيانات - يكتب ؛

حذف عامل التشغيل

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





# حذف pointer_variable ؛

مثال 1

في هذا المثال ، سنقدم مؤشرين: أحدهما مؤشر نوع عدد صحيح والآخر مؤشر عائم. يتم تهيئة المؤشرات باستخدام علامة النجمة معهم.

# Int * pointInt ؛
# Float * pointfloat ؛

باستخدام هاتين الطابعتين ، سنخصص الذاكرة ديناميكيًا.



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

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

# نقطة = كثافة العمليات الجديدة ؛

وبالمثل ، فإن المؤشر العائم مرتبط بالمثل. بعد عملية الربط ، سنخصص أي قيمة للذاكرة التي نريد حجزها لأي عملية. من خلال الإعلان عن المؤشر ، نقوم بتعيين قيمة محددة للذاكرة.

# * pointInt = 50 ؛

يتم أيضًا الإعلان عن قيمة عائمة لعوامات النقطة. اعرض القيم بعد التعيين.

كما ناقشنا ، يتم استخدام عامل التشغيل 'الجديد' للتخصيص بينما يتم استخدام 'delete' لإلغاء تخصيص الذاكرة. لذلك بمجرد الانتهاء من المهمة أو العملية في الكود ، سنزيل الذاكرة التي خصصناها للمهمة.

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

نقطة الحذف يطفو ؛

بمجرد حفظ الكود في محرر النصوص ، تسمح لك محطة Ubuntu بتنفيذ الكود المصدري داخل الملف من خلال مترجم g ++.

$ g ++ -o mem.c
$ ./mem

عند التنفيذ ، سترى القيم المخصصة للذاكرة.

مثال 2

هذا المثال له دور في تفاعل المستخدم. سنأخذ متغير رقم يحتوي على قيمة من المستخدم. سيقوم هذا البرنامج بتخزين النتيجة في المعدل التراكمي للطلاب. سيتم حفظ جميع النتائج في وقت التشغيل.

عندما يقوم المستخدم بإدخال عدد الطلاب ، يتم تخصيص الذاكرة مقابل كل رقم. يتم هنا تهيئة مؤشر نوع عائم ليتم استخدامه في تخصيص الذاكرة للنتائج.

نأخذ المؤشر في وضع عائم نظرًا لأن المعدل التراكمي يكون بالتدوين العشري. نأخذ مصفوفة من نوع المؤشر لـ GPA حيث يمكن أن ينتج عنها عدد من الطلاب.

Ptr = الجديد يطفو [ على واحد ]

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

حذف [ ] ptr ؛

الآن سنقوم بتنفيذ الكود المذكور أعلاه. سيُطلب من المستخدم أولاً إدخال عدد الطلاب. ثم يتم إدخال المعدل التراكمي لكل طالب.

مثال 3

يستخدم هذا المثال عوامل التشغيل الجديدة وعوامل الحذف لكائن الفئة. تحتوي هذه الفئة على متغير خاص من نوع عدد صحيح يخزن العمر. في الجزء العام من الفصل ، يتم إنشاء المُنشئ الذي سيهيئ العمر إلى رقم '10'. يتم استخدام دالة أخرى هنا تعرض العمر الذي تمت تهيئته في المنشئ.

الآن سوف نتجه نحو البرنامج الرئيسي للتخصيص الديناميكي. يتم إنشاء كائن الفصل ديناميكيًا.

طالب علم * ptr = الجديد طالب علم ( ) ؛

عندما يتم تشكيل الكائن ، سيتم تنفيذ المنشئ تلقائيًا. سيتم إجراء مكالمة دالة لمعرفة العمر. سيتم ذلك من خلال ptr.

Ptr - > getAge ( ) ؛

وفي النهاية سيتم تحرير الذاكرة.

استنتاج

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