ماذا يحدث إذا قمت بإعادة التالفة والحجم الجديد هو 0. هل هذا مكافئ مع مجاني؟

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

  •  23-09-2019
  •  | 
  •  

سؤال

بالنظر إلى الرمز التالي:

int *a = NULL;
a = calloc(1, sizeof(*a));
printf("%d\n", a);
a = realloc(a, 0);

printf("%d\n", a);
return (0);

يعود:

4078904
0

هل هذا ما يعادل مجانا؟

ملاحظة: أنا أستخدم Mingw ضمن WindowsXP.

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

المحلول

ليس بالضرورة.

غالبًا ما يفعل كما هو ارتباط أن Munissor نشر, ، لكن صفحة MAC OS 10.5 MAN تقول:

إذا كان الحجم صفرًا ولم يكن PTR فارغًا ، فسيتم تخصيص كائن جديد وحجم الحد الأدنى ويتم تحرير الكائن الأصلي.

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

أظن أن هذا الحكم موجود لدعم التطبيقات الموجودة في وقت التقييس ، وأن هذه التطبيقات مفيدة لسلوك تخصيص الأخطاء.


إلى عنوان تعليقات جوناثان

النظر في الفرق بين

for (int i=0; i<VERY_BIG_NUMBER; ++i){
  char *p = malloc(sizeof(char[10]));
  free(p);
}

و

for (int i=0; i<VERY_BIG_NUMBER; ++i){
  char *p = malloc(sizeof(char[10]));
  realloc(p,0);
}

مع تنفيذ عاقل ل malloc و free المقطع الأول يفعل ليس تستهلك الذاكرة بدون ملزمة. ولكن إذا realloc يقوم التنفيذ بإرجاع تلك "الكائنات الدنيا الحجم" التي قد.

من المؤكد أن هذا المثال مفتعل ويعتمد على فهم ما هو المقصود بـ "كائن الحد الأدنى" ، لكنني أعتقد أن هذا النص يسمح بذلك.

باختصار ، إذا كنت تعني free يجب عليك القول free.

نصائح أخرى

قد يكون أو لا يكون مكافئًا للاتصال free على المؤشر والنتيجة محددة التنفيذ.

من معيار C99 (§7.20.3/1):

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

ينطبق على جميع وظائف إدارة الذاكرة ، بما في ذلك realloc.

نعم

يقول C99 القياسي §7.20.3.4 (RealLoc):

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

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

هذا ينص بوضوح على أن الكائن القديم يتم تعديله (محرره). قد تكون قيمة الإرجاع مؤشرًا فارغًا ، أو قد تكون قيمة كما هو محدد في الملاحظات العامة للفقرة 7.20.3:

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

في كلتا الحالتين ، لا يمكنك إطفاء القيمة التي تم إرجاعها: يمكن استخدامها كوسيطة free(), ، أو انتقل إلى وظائف أخرى طالما أنها بدورها لا تشير إليها.

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