كيفية تحديث المؤشرات الأخرى عندما يقوم Realloc بتحريك كتلة الذاكرة؟
سؤال
المرجع Realloc يقول:
قد تنقل الوظيفة كتلة الذاكرة إلى موقع جديد ، وفي هذه الحالة يتم إرجاع الموقع الجديد.
هل يعني ذلك أنه إذا قمت بذلك:
void foo() {
void* ptr = malloc( 1024 );
unsigned char* cptr = ( unsigned char* )ptr+256;
ptr = realloc( ptr, 4096 );
}
ثم قد تصبح CPTR غير صالحة إذا قام RealLoc بتحريك الكتلة؟
إذا كانت الإجابة بنعم ، فعندئذٍ ، هل تشير Realloc بأي شكل من الأشكال ، أنه سيحرك الكتلة ، حتى أتمكن من فعل شيء لمنع CPTR من أن يصبح غير صالح؟
المحلول
نعم، cptr
سوف تصبح غير صالحة لأن Realloc تحرك الكتلة! ولا ، لا يوجد ذكر للإشارة إليك لتخبرها أنها تحرك كتلة الذاكرة. بالمناسبة ، يبدو الكود الخاص بك iffy ... اقرأ ... يرجى الاطلاع إجابه لسؤال آخر وقراءة الكود بعناية فائقة حول كيفية استخدامه realloc
. الإجماع العام هو إذا قمت بذلك:
void *ptr = malloc(1024); /* later on in the code */ ptr = realloc(ptr, 4096); /* BAM! if realloc failed, your precious memory is stuffed! */
طريقة الالتفاف حولها هي استخدام مؤشر مؤقت واستخدام ذلك كما هو موضح:
void *ptr = malloc(1024); /* later on in the code */ void *tmp = realloc(ptr, 4096); if (tmp != null) ptr = tmp;
تعديل: شكرًا يؤمن للإشارة إلى gremlin التي تسللت عندما كنت أكتب هذا في وقت سابق.
نصائح أخرى
نعم، cptr
سيصبح غير صالح إذا قام RealLoc بتحريك الكتلة.
لا ، لا توجد إشارة. سيكون عليك التحقق من قيمة الإرجاع مقابل الأصل ptr
موقعك.
هذا متأخر بعض الشيء ، لكن الحل لهذه المشكلة (التي لم يذكرها أحد) لا يستخدم مؤشرات في كتل مخصصة يجب تخصيصها. بدلاً من ذلك ، استخدم الإزاحة ذات القيمة العددية من المؤشر الأساسي أو (أفضل) استخدام أ struct
اكتب وعناصر الأعضاء لمعالجة مواقع محددة في الكائن المخصص.
نعم.
أفضل شيء القيام به هو مقارنة PTR قبل وبعد إعادة التخصيص ، ومعرفة ما إذا كان قد تم نقله. لا يجب عليك تعيين مؤشر إلى قيمة الإزاحة ، بدلاً من ذلك يجب عليك تخزين الإزاحة ثم فهرسة المشغل الأصلي معه.
بمعنى آخر
بدلاً منvoid* newPtr = ptr + 10;
*newPtr = something;
يستخدمint new = 10;
ptr[new] = something;
نعم ، يصبح CPTR غير صالح إذا قام RealLoc بتحريك الكتلة.