Повреждение памяти на нескольких 'strcat' с одним и тем же src - PullRequest
0 голосов
/ 07 июня 2019

Это очень простая проблема, но я ошеломлен тем, что не могу найти легкое решение. Я пытаюсь создать две строки, которые являются путем к файлам. / Метаданные / битовая карта /Metadata/Metadata.bin

но во второй раз, когда я пытаюсь сделать strcat() с той же переменной src, происходит повреждение памяти

//create the dir strign to append
    char* metadata_dir = strdup(MNT_POINT);
    strcat(metadata_dir, "Metadata/");


    char* bitmap_file = strdup("");
    strcat(bitmap_file,metadata_dir);
    strcat(bitmap_file,"bitmap");
    printf("%s\n",bitmap_file);


    char* meta_file = strdup("");
    strcat(meta_file, metadata_dir);
    strcat(meta_file, "Metadata.bin");
    printf("%s\n",meta_file);

Rigth в линии strcat(meta_file, metadata_dir); происходит повреждение памяти.

Я уверен, что metadata_dir не поврежден, потому что я могу напечатать его в любом месте кода, и он выглядит хорошо.

Странно то, что это происходит в зависимости от машины, на которой он работает. В Ubuntu 64 работает просто отлично. Но в 32-битной версии нет.

Ответы [ 2 ]

4 голосов
/ 07 июня 2019

strdup гарантированно вернет буфер, достаточно большой для дублируемой строки (с нулевым терминатором); у него может не быть (и часто не будет) места для объединения других вещей с ним. Вы перезаписываете случайную память, когда пишете после конца строки с помощью strcat.

РЕДАКТИРОВАТЬ: решение, конечно, состоит в том, чтобы malloc буфер был достаточно большим заранее, вместо того, чтобы strdup делал это.

0 голосов
/ 07 июня 2019

Код не выполняется, поскольку metadata_dir достаточно велик только для MNT_POINT, а не MNT_POINT и "Metadata/"

char* metadata_dir = strdup(MNT_POINT);
strcat(metadata_dir, "Metadata/");

Для выделения и сцепления:

char *allocate_cat(const char *s1, const char *s2) {
  size_t len1 = strlen(s1);
  size_t size2 = strlen(s2) + 1;
  char *s12 = malloc(len1 + size2);  // allocate enough room for both
  if (s12) {
    memcpy(s12, s1, len1);
    memcpy(s12 + s1, s2, size2);
  }
  return s12;
}
...