تخصيص الذاكرة القائم على المكدس

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

تُعد المكدسات في بنى الحوسبة مناطق من الذاكرة حيث تتم إضافة البيانات أو إزالتها بطريقة "آخر ما يدخل أول ما يخرج" (LIFO) .

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

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

المزايا والعيوب

نظرًا لأن البيانات تتم إضافتها وإزالتها بطريقة "آخر ما يدخل أول ما يخرج"، فإن تخصيص الذاكرة القائم على المكدس بسيط للغاية وعادة ما يكون أسرع بكثير من تخصيص الذاكرة القائم على الكومة (المعروف أيضًا باسم تخصيص الذاكرة الديناميكي ) على سبيل المثال لغة C.malloc

من الميزات الأخرى استعادة الذاكرة من المكدس تلقائيًا وبكفاءة عالية عند انتهاء الدالة، مما يُسهّل على المبرمج استخدام البيانات إذا لم تعد مطلوبة. [ 1 ] (وينطبق الأمر نفسه على دالة longjmp إذا انتقلت إلى نقطة قبل استدعاء الدالة alloca). مع ذلك، إذا كانت البيانات بحاجة إلى الاحتفاظ بها بشكل ما، فيجب نسخها من المكدس إلى الكومة قبل انتهاء الدالة. لذا، يُعدّ تخصيص الذاكرة القائم على المكدس مناسبًا للبيانات المؤقتة أو البيانات التي لم تعد مطلوبة بعد انتهاء الدالة الحالية.

قد يصل حجم مكدس الذاكرة المخصص للخيط إلى بضعة بايتات فقط على بعض وحدات المعالجة المركزية الصغيرة. ويمكن أن يؤدي تخصيص ذاكرة أكبر من المتاحة في المكدس إلى حدوث عطل بسبب تجاوز سعة المكدس . لهذا السبب أيضًا، allocaيُمنع عادةً تضمين الدوال التي تستخدم هذه الخاصية: [ 2 ] فإذا تم تضمين دالة كهذه في حلقة تكرارية، فسيتعرض المستدعي لزيادة غير متوقعة في استخدام المكدس، مما يزيد من احتمالية حدوث تجاوز السعة.

قد يتسبب تخصيص الذاكرة القائم على المكدس في مشاكل طفيفة في الأداء: إذ يؤدي إلى إطارات مكدس متغيرة الحجم، مما يستلزم إدارة كل من مؤشرات المكدس والإطار (مع إطارات المكدس ثابتة الحجم، يصبح مؤشر المكدس زائداً عن الحاجة نتيجة ضرب مؤشر إطار المكدس بحجم كل إطار). عادةً ما يكون هذا أقل تكلفة بكثير من استدعاء دالة ` mallocalloca` free. على وجه الخصوص، إذا احتوت الدالة الحالية على استدعاءات لدالة ` allocaalloca` وكتل تحتوي على بيانات محلية متغيرة الطول، فسيحدث تعارض بين محاولات `alloca` لزيادة إطار المكدس الحالي حتى انتهاء الدالة الحالية، وحاجة المُصرّف لوضع متغيرات محلية متغيرة الطول في نفس الموقع في إطار المكدس. يُحل هذا التعارض عادةً بإنشاء سلسلة تخزين منفصلة في الكومة لكل استدعاء لدالة `alloca` alloca. [ 3 ] تسجل هذه السلسلة عمق المكدس الذي يحدث عنده كل تخصيص، وتقوم الاستدعاءات اللاحقة لدالة `alloca` allocaفي أي دالة بتقليص هذه السلسلة إلى عمق المكدس الحالي لتحرير أي مساحة تخزين عليها في النهاية (ولكن ليس فوراً). يمكن أيضاً استخدام استدعاء دالة `alloca` allocaمع وسيط قيمته صفر لتحرير الذاكرة دون تخصيص المزيد منها. ونتيجة لهذا التعارض بين allocaالتخزين المحلي وتخزين المتغيرات، allocaقد لا يكون استخدام التخزين المحلي أكثر كفاءة من استخدام التخزين المحلي malloc.

واجهة النظام

تُطبّق العديد من الأنظمة الشبيهة بنظام يونكس، بالإضافة إلى نظام مايكروسوفت ويندوز، دالةً تُسمى `resource` allocaلتخصيص ذاكرة المكدس ديناميكيًا بطريقة مشابهة للتخصيص القائم على الكومة malloc. يقوم المُصرّف عادةً بترجمتها إلى تعليمات مُضمّنة تُعالج مؤشر المكدس، على غرار كيفية التعامل مع المصفوفات ذات الأطوال المتغيرة . [ 4 ] على الرغم من عدم الحاجة إلى تحرير الذاكرة صراحةً، إلا أن هناك خطر حدوث سلوك غير مُعرّف بسبب تجاوز سعة المكدس. [ 5 ] كانت هذه الدالة موجودة في أنظمة يونكس منذ الإصدار 32/V (1978)، ولكنها ليست جزءًا من معيار C أو أي معيار POSIX .

يوجد إصدار أكثر أمانًا من هذه allocaالدالة، يُسمى `request` _malloca، والذي يُخصص الذاكرة على الكومة إذا كان حجم التخصيص كبيرًا جدًا، ويُبلغ عن أخطاء تجاوز سعة المكدس، على نظام التشغيل مايكروسوفت ويندوز. ويتطلب هذا الإصدار استخدام `request` _freea. [ 6 ] توفر مكتبة gnulib واجهة مكافئة، ولكن بدلًا من طرح استثناء SEH عند تجاوز السعة، فإنها تُحيل الأمر إلى `request` mallocعند اكتشاف حجم كبير جدًا. [ 7 ] يمكن محاكاة ميزة مماثلة باستخدام المحاسبة اليدوية وفحص الحجم، كما هو الحال في استخدامات `request` alloca_accountفي مكتبة glibc. [ 8 ]

تحتوي بعض عائلات المعالجات، مثل x86 ، على تعليمات خاصة لمعالجة مكدس الخيط قيد التنفيذ حاليًا. أما عائلات المعالجات الأخرى، بما في ذلك RISC-V و PowerPC و MIPS ، فلا تدعم المكدس بشكل صريح، بل تعتمد على الاصطلاحات وتفوض إدارة المكدس إلى واجهة التطبيق الثنائية (ABI) لنظام التشغيل .

وكالات تسجيل المركبات الآلية

بالإضافة إلى ذلك، منذ إصدار C99 من لغة C (اختياري منذ C11)، أصبح من الممكن إنشاء مصفوفة على المكدس داخل دالة، تلقائيًا، وهو ما يُعرف باسم المصفوفة ذات الطول المتغير التلقائية ( auto VLA ). [ 9 ] مع ذلك، لا تدعم لغة C++ هذه الميزة. [ 10 ]

void f ( int len ​​) { // مصفوفة VLA تلقائية - يتم تحديد طول هذه المصفوفة عند // وقت استدعاء الدالة / إنشاء المكدس. int b [ len ]; // مصفوفة VLA تلقائية - يتم تحديد طول هذه المصفوفة عند for ( int i = 0 ; i < len ; i ++ ) { b [ i ] = 1 ; } // في نهاية هذه الدالة، يكون b داخل إطار المكدس، وسوف // يختفي عند انتهاء الدالة، لذلك لا يلزم استدعاء صريح لـ free(). }

انظر أيضاً

مراجع

  1. "مزايا Alloca" . مكتبة GNU C.
  2. "مضمن" . باستخدام مجموعة مترجمات جنو (GCC) .
  3. "شفرة المصدر Alloca.c [ libiberty/Alloca.c ] - Codebrowser" .
  4. دليل مبرمج لينكس – وظائف المكتبةalloca(3)  
  5. "لماذا لا يُعتبر استخدام دالة alloca() ممارسة جيدة؟" . stackoverflow.com . تم الاطلاع عليه بتاريخ 2016-01-05 .
  6. "_malloca" . وثائق مايكروسوفت CRT .
  7. "gnulib/malloca.h" . GitHub . تم الاطلاع عليه بتاريخ 24 نوفمبر 2019 .
  8. "glibc/include/alloca.h" . مرايا بيرين مينور. 23 نوفمبر 2019.
  9. "تعريف ISO C 99" (ملف PDF) . تم الاطلاع عليه بتاريخ 10-04-2022 .
  10. "تعريف المصفوفة" . cppreference.com . تم الاطلاع عليه بتاريخ 12 سبتمبر 2025 .