asprintf перезапись памяти для перераспределения


У меня есть следующий код, который не работает при использовании как asprintf, так и realloc.

Ошибка, которую я получаю:

*** glibc detected *** a.out: realloc(): invalid old size: 0x006f1430 ***
Основываясь на том, что я исследовал, это выглядит так, когда я использую asprintf, это перезапись некоторой памяти, которую использует realloc. Это не имеет смысла для меня, так как asprintf должен быть безопасным и динамически выделять, используя соответствующую длину строки. Не используя asprintf заставляет программу работать нормально, но мне нужна функциональность asprintf для моего проект.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  int ifCount = 1;
  int stringCount = 1;
  char** IFs = NULL;

  //Broken code
  char* message;
  asprintf(&message, "Hello: %d", stringCount);

  //Working code, but not the alternative I want to take
  //char* message = "Hello";

  IFs = (char**) realloc(IFs, sizeof(char*) * ifCount);
  IFs[ifCount - 1] = (char*) realloc(IFs[ifCount - 1], sizeof(char) * strlen(message));
  strcpy(IFs[ifCount - 1], message);

  printf("Message: %sn", message);
  printf("Copy: %sn", IFs[ifCount - 1]);
  free(message);
}
2 2

2 ответа:

Это:

IFs[ifCount - 1] = (char*) realloc(IFs[ifCount - 1], sizeof(char) * strlen(message));

Передает неинициализированный указатель на realloc(), что является причиной ошибки.

Также:

  1. помните, что строки нуждаются в пространстве завершения, выше выделяются символы strlen(message), которых слишком мало. Это приведет к переполнению буфера strcpy() При копировании.
  2. Пожалуйста, помните, что realloc(), как и все функции, выделяющие память кучи, может произойти сбой. Это справедливо и для asprintf().
  3. не бросайте возвращаемое значение realloc() в C .
  4. избегайте sizeof (char), так как это всегда 1, это добавляет очень мало значения в код.

Вместо того, чтобы использовать realloc с NULL или неинициализированным первым аргументом, просто используйте malloc Для начала.

Если вызов realloc необходим в вызове IFs[ifCount - 1] = (char*) realloc(...), то в предыдущей строке используйте вместо него calloc - это по крайней мере обнулит выделенную память, так что realloc будет дан правильный указатель NULL.