كيفية تحديث المؤشرات الأخرى عندما يقوم Realloc بتحريك كتلة الذاكرة؟

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

  •  24-09-2019
  •  | 
  •  

سؤال

المرجع 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 بتحريك الكتلة.

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