خطأ مالوك:المجموع الاختباري غير صحيح للكائن المحرر

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

  •  04-07-2019
  •  | 
  •  

سؤال

أنا أعمل على تنفيذ ذيل لمهمة ما.لقد عملت بشكل صحيح ولكن يبدو أنني أتلقى خطأً من الخدمة المجانية في أوقات عشوائية.

لا أستطيع أن أرى، لتعقبه إلى نمط أو أي شيء إلى جانب أنه متسق.

على سبيل المثال، إذا قمت باستدعاء برنامجي باسم "tail -24 test.in" فسأحصل على خطأ المجموع الاختباري غير الصحيح في نفس السطر عند عمليات التشغيل المتعددة.ومع ذلك، مع وجود ملفات مختلفة وحتى أعداد مختلفة من الأسطر المراد طباعتها، سأعود دون أخطاء.

إذا كانت لديك أي فكرة عن كيفية تعقب المشكلة، فقد كنت أحاول تصحيحها لساعات دون جدوى.

إليك الكود المخالف:

يتم تعريف الخطوط على أنها char ** وكانت malloc على النحو التالي:

lines = (char**) malloc(nlines * sizeof(char *));

void insert_line(char *s, int len){

  printf("\t\tLine Number: %d Putting a %d line into slot: %d\n",processed,len,slot);
  if(processed > numlines -1){//clean up
    free(*(lines+slot));
    *(lines + slot) = NULL;
  }
  *(lines + slot) = (char *) malloc(len * sizeof(char));
  if(*(lines + slot) == NULL) exit(EXIT_FAILURE);
  strcpy(*(lines+slot),s);
  slot = ++processed % numlines;
}
هل كانت مفيدة؟

المحلول

والروتين الخاص بك هو كتابة خارج المخزن المؤقت خط المخصصة.

وحجم الخط مرت كحجة (أي "ليون") ربما لا يتضمن فاصل NUL. عند استدعاء malloc لنسخ خط (أي "ليالي") تحتاج إلى تخصيص بايت إضافية للفاصل سلسلة:

 *(lines + slot) = (char *) malloc((len + 1) * sizeof(char));

نصائح أخرى

إذا كان بإمكانك إعادة إنتاج المشكلة باستمرار باستخدام معلمات إدخال محددة، فيجب عليك تصحيح الأخطاء على النحو التالي:

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

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

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

  *(lines + slot) = (char *) malloc(len * sizeof(char));
  if(*(lines + slot) == NULL) exit(EXIT_FAILURE);
  strcpy(*(lines+slot),s);

وربما محاولة:

  lines[slot] = (char *) malloc((len + 1) * sizeof(char));
  if(lines[slot] == NULL) exit(EXIT_FAILURE);
  if(strlen(s) <= len){
    strcpy(lines[slot],s);
  }
  else{
    /* do something else... */
  }

في حيث الشكل العام، ويهمني أيضا تشجيع لك لجعل بعض التغييرات الأسلوبية لجعل كل شيء قليلا أكثر قابلية للقراءة، وأسهل لمتابعة ومقاومة للأخطاء.

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

free(lines[slot]);
lines[slot] = NULL;

وبدلا من

free(*(lines+slot));
*(lines + slot) = NULL;

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

static int numlines = 0;
void insert_line(char *s, int len){
    int numlines = 5;

وحيث يمكنك إدخال القضايا الاستطلاعية التي هي مجرد بائسة التصحيح.

هل NLINES وnumlines لها نفس القيمة؟

هل المتصل من insert_line يسمح المجال لNUL زائدة عند تمرير طول في المعلمة الثانية؟

ولست متأكدا من انها ذات الصلة ولكن هذين الخطين يبدو المشبوهة لي:

  *(lines + slot) = (char *) malloc(len * sizeof(char));
  if((lines + slot) == NULL) exit(EXIT_FAILURE);

وعليك أولا تعيين عودة malloc إلى lines[slot] ثم تحقق (lines+slot)، إذا كان هذا الأخير فارغة، وكنت قد dereference مؤشر NULL!

وأيضا إذا خطوط [فتحة] (* بك (خطوط + فتحة)) ليست لاغية، سوف تسرب الذاكرة عند وتعيين نتيجة malloc () لذلك.

وأفترض lines هو char * خطوط [] `وفتحة يقع ضمن الحدود المسموح بها!

وأنا أتفق مع اشتباه ريمو بشأن هذين الخطين، ولكن ليس الظل التي ريمو انفجرت على. علينا أن نشارك الائتمان للعثور على هذا الخطأ.

*(lines + slot) = some value
if((lines + slot) == NULL) then die
should be
if(*(lines + slot) == NULL) then die
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top