سؤال

تحمل معي. لم أكن مشفرًا في C منذ 8 سنوات ، وأنا محير تمامًا لماذا لا يعمل معالجة السلسلة الخاصة بي. أنا أكتب برنامجًا يحلق إلى الأبد. في الحلقة ، أقوم بتهيئة مؤشرين char لكل منهما إلى وظيفة تضيف نصًا إلى مؤشر char (صفيف). عند الانتهاء من الوظائف ، أقوم بطباعة مؤشر Char وحرر مؤشرات Char. ومع ذلك يموت البرنامج بعد 7 تكرارات مع رسالة الخطأ التالية

* glibc اكتشف * ./Test: مجاني مزدوج أو فساد (FastTop): 0x0804A168 ***

#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include string.h
#include stdio.h
#include stdlib.h
#include errno.h
#include time.h

char *SEPERATOR = "|";

void getEvent (char* results);
void getTimeStamp(char* timeStamp, int timeStampSize);
void stringAppend(char* str1, char* str2);

int main (int argc, char *argv[])
{
  int i = 0; 
  while(1)
  { 
    i++;
    printf("%i", i);    

    char* events= realloc(NULL, 1); 
    events[0] = '\0';
    getEvent(events);

    char* timestamp= realloc(NULL, 20);
    timestamp[0] = '\0';
    getTimeStamp(timestamp, 20);

    printf("%s", events);
    printf("timestamp: %s\n", timestamp);

    free(events);
    free(timestamp);
  } 
}

void getEvent (char* results)
{
  stringAppend(results, "a111111111111");
  stringAppend(results, "b2222222222222");
}

void getTimeStamp(char* timeStamp, int timeStampSize)
{
  struct tm *ptr;
  time_t lt;
  lt = time(NULL);
  ptr = localtime(&lt);
  int r = strftime(timeStamp, timeStampSize, "%Y-%m-%d %H:%M:%S", ptr);
}

void stringAppend(char* str1, char* str2)
{   
  int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1;
  printf("--%i--",arrayLength);

  str1 = realloc(str1, arrayLength);
  if (str1 != NULL)
  {
    strcat(str1, SEPERATOR);
    strcat(str1, str2);
  }
  else
  {
    printf("UNABLE TO ALLOCATE MEMORY\n");
  }
}
هل كانت مفيدة؟

المحلول

المشكلة هي أنه بينما تقوم StringAppend بإعادة تخصيص المؤشرات ، إلا أن StringAppend يدرك هذه الحقيقة. تحتاج إلى تعديل stringappend لأخذ المؤشر إلى الرميات (char **) بحيث يتم تحديث المؤشرات الأصلية.

نصائح أخرى

أنت تخصيص str1 ولكن لا تمرير القيمة خارج وظيفتك ، لذلك يتم تسريب المؤشر المحتمل الذي تم تغييره ، والقيمة القديمة ، التي تم تحريرها بواسطة realloc, ، يتم تحريره مرة أخرى من قبلك. هذا يسبب تحذير "مجاني مزدوج".

هذا الخط في StringAppend:

str1 = realloc(str1, arrayLength);

يغير قيمة المتغير المحلي في StringAppend. يشير هذا المتغير المحلي المسمى STR1 الآن إلى الذاكرة المخصصة أو الفارغة.

في هذه الأثناء ، تحتفظ المتغيرات المحلية في GetEvent بالقيم التي كانت لها من قبل ، والتي عادة ما تشير إلى الذاكرة المحررة.

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

لكل من getevent و stringappend أعيد مؤشر char.

على سبيل المثال

char* stringAppend(char* str1, char* str2) 
{    
  int arrayLength = strlen(str1) + strlen(str2) + strlen(SEPERATOR) + 1; 
  printf("--%i--",arrayLength); 

  str1 = realloc(str1, arrayLength); 
  if (str1 != NULL) 
  { 
    strcat(str1, SEPERATOR); 
    strcat(str1, str2); 
  } 
  else 
  { 
    printf("UNABLE TO ALLOCATE MEMORY\n"); 
  } 
  return str1;
} 

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

char* events= realloc(NULL, 1); 
events[0] = '\0';

أنت لا تختبر ذلك realloc تخصيص الذاكرة بنجاح.

char* timestamp= realloc(NULL, 20);
timestamp[0] = '\0';

نفس المشكلة هنا. في هذه الحالة ، لا تحتاج realloc على الاطلاق. نظرًا لأن هذا عازلة ذات حجم ثابت ، يمكنك استخدام فقط:

char timestamp[20] = "";

ولا تفعل هذا:

str1 = realloc(str1, arrayLength);

لأنه إذا realloc يفشل ، سوف يتيمة الذاكرة str1 كان يشير إلى قبل. في حين أن:

char* temp = realloc(str1, arrayLength);
if (temp != NULL)
{
    str1 = temp;
    ...
}

لاحظ أنه نظرًا لأنك تعدل stringAppend لإرجاع السلسلة الجديدة ، يجب عليك إجراء فحوصات مماثلة في وظائف الاتصال.

أيضا ، "فاصل" مكتوبة مع اثنين AS ، ليس مع اثنين es.

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