ماذا سيفعل Realloc إذا لم يكن هناك مساحة متسلسلة للذاكرة؟

StackOverflow https://stackoverflow.com/questions/3684288

سؤال

realloc يستخدم لإعادة تخصيص الذاكرة ديناميكيا.

افترض أنني قمت بتخصيص 7 بايت باستخدام malloc وظيفة والآن أريد تمديدها إلى 30 بايت.

ماذا سيحدث في الخلفية إذا لم يكن هناك مساحة متسلسلة (مستمر في صف واحد) من 30 بايت في الذاكرة؟

هل هناك أي خطأ أو سيتم تخصيص الذاكرة في أجزاء؟

هل كانت مفيدة؟

المحلول

realloc يعمل خلف الكواليس تقريبًا مثل هذا:

  • إذا كان هناك مساحة حرة كافية خلف الكتلة الحالية للوفاء بالطلب ، فقم بتمديد الكتلة الحالية وإعادة مؤشر إلى بداية الكتلة.
  • وإلا إذا كان هناك كتلة مجانية كبيرة بما يكفي في مكان آخر ، فقم بتخصيص هذه الكتلة ، ونسخ البيانات من الكتلة القديمة ، وحرر الكتلة القديمة وإرجاع مؤشر إلى بداية الكتلة الجديدة
  • آخر تقرير الفشل من خلال العودة NULL.

لذلك ، يمكنك اختبار الفشل عن طريق الاختبار NULL, ، لكن كن على علم بأنك لا تكتب المؤشر القديم مبكرًا جدًا:

int* p = malloc(x);
/* ... */
p = realloc(p, y); /* WRONG: Old pointer lost if realloc fails: memory leak! */
/* Correct way: */
{
  int* temp = realloc(p, y);
  if (NULL == temp)
  {
    /* Handle error; p is still valid */
  }
  else
  {
    /* p now possibly points to deallocated memory. Overwrite it with the pointer
       to the new block, to start using that */
    p = temp;
  }
}

نصائح أخرى

realloc لن ينجح إلا إذا تمكنت من إرجاع كتلة الذاكرة المتجاورة ("المتسلسلة" في كلماتك). إذا لم يكن هناك مثل هذا الكتلة ، فسوف يعود NULL.

من صفحة الرجل:

تقوم RealLoc () بإرجاع مؤشر إلى الذاكرة المخصصة حديثًا ، والتي يتم محاذاة بشكل مناسب لأي نوع من المتغيرات وقد تكون مختلفة عن PTR ، أو NULL في حالة فشل الطلب.

وبعبارة أخرى ، لاكتشاف الفشل ، فقط تحقق مما إذا كانت النتيجة فارغة.

تحرير: كما لوحظ في التعليق ، إذا فشلت المكالمة ، لم يتم تحرير الذاكرة الأصلية.

بشكل عام ، يعتمد ذلك على التنفيذ. في X86 (-64) Linux ، أعتقد أن خوارزمية Doug Lea Malloc القياسية ستقوم دائمًا بتخصيص ما لا يقل عن صفحة قياسية X86 (4096 بايت) ، لذا بالنسبة للسيناريو الذي وصفته أعلاه ، فإنه سيعيد ضبط الحدود لإقامة البايتات الإضافية. عندما يتعلق الأمر ، على سبيل المثال ، إعادة تخصيص عازلة من 7Bytes إلى page_size+1 أعتقد أنه سيحاول تخصيص الصفحة المتجاورة التالية إذا كان ذلك متاحًا.

يستحق قراءة ما يلي ، إذا كنت تتطور على Linux:

بشكل افتراضي ، تتبع Linux استراتيجية تخصيص الذاكرة المتفائلة. هذا يعني أنه عندما يعيد Malloc () غير خارق ، لا يوجد ضمان بأن الذاكرة متوفرة بالفعل. هذا خطأ سيء حقا. في حال اتضح أن النظام خارج الذاكرة ، سيتم قتل عملية واحدة أو أكثر من قاتل OOM سيئ السمعة. في حالة استخدام Linux في ظل ظروف يكون من المستحسن أن تفقدها فجأة بعض العمليات التي تم اختيارها عشوائيًا ، وعلاوة على ذلك ، فإن إصدار kernel حديث بما فيه الكفاية ، يمكن للمرء إيقاف هذا السلوك المفرط باستخدام أمر مثل:

# echo 2 > /proc/sys/vm/overcommit_memory

راجع أيضًا دليل وثائق kernel ، والملفات VM/OverCommit-accounting و SYSCTL/VM.TXT.

تحتوي FreeBSD و Mac OS X على وظيفة RealLocf () التي ستحرر المؤشر الذي تم تمريره عندما لا يمكن تخصيص الذاكرة المطلوبة (انظر Man Realloc).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top