Realloc и свободные причины «двойной свободный или коррупция»

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

Вопрос

Потерпите меня. Я не закодировал в C в 8 лет и полностью сбил сбившись, почему мои струнные манипуляции не работают. Я пишу программу, которая цикла вечно. В цикле я инициализирую две указатели CHAR, каждый передается функции, которая добавляет текст на указатель CHAR (массив). Когда функции выполняются, я печатаю указатель CHAR и освободить два указателя Char. Однако программа умирает после 7 итераций со следующим сообщением об ошибке

* обнаружил Glibc * ./test: двойной бесплатный или коррупция (фастмонтаж): 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 перераспределяет указатели, только StrateAppend осознает этот факт. Вам необходимо изменить stringappend, чтобы принять указатель-указатели (char **), чтобы оригинальные указатели обновлены.

Другие советы

Вы перераспределяете str1 Но не передавать значение из вашей функции, поэтому потенциально измененный указатель протекает, а старое значение, которое было освобождено realloc, освобождается снова вами. Это вызывает предупреждение «Double Free».

Эта линия в stringAppend:

str1 = realloc(str1, arrayLength);

Изменяет значение локальной переменной в stringAppend. Эта локальная переменная названа STR1 теперь указывает на перераспределенную память или NULL.

Между тем местные переменные в 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 Чтобы вернуть новую строку, вы должны делать аналогичные проверки в функциях вызывающих.

Кроме того, «сепаратор» пишется с двумя, а не с двумя эс.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top