освобожденный указатель не был выделен (только для osx) - PullRequest
0 голосов
/ 23 декабря 2011

Функция ниже в основном эмулирует mkdir -p, рекурсивно создавая каталоги для заданного пути.С Linux у меня нет проблем, однако при работе под OSX всегда происходит сбой с ошибкой pointer being freed was not allocated во время вызова free(dir).Может кто-нибудь заметить ошибку?Когда я выполняю выполнение в gdb, я не вижу никаких очевидных проблем, dir заполняется, и структура каталогов создается без ошибок.

static int
mkpath(const char *path)
{
  int result = 0;
  struct stat st;
  char *p = NULL, *dir = strdup(path);
  char *tmp = g_malloc0(sizeof(char) * strlen(cache.path) + strlen(dir) + 1);

  dir = dirname(dir);
  tmp = strcpy(tmp, cache.path);
  p = strtok(dir, "/");
  while(p != NULL) {
    tmp = strncat(tmp, "/", 1);
    tmp = strncat(tmp, p, strlen(p));

    if(stat(tmp, &st) == 0) {
      if(S_ISDIR(st.st_mode)) {
        p = strtok(NULL, "/");
        continue;
      }

      result = -ENOTDIR;
      break;
    }

    if(mkdir(tmp, S_IRWXU) == -1) {
      result = -errno;
      break;
    }

    p = strtok(NULL, "/");
  }

  free(tmp);
  free(dir);

  return result;
}

Ответы [ 3 ]

3 голосов
/ 23 декабря 2011

Взгляните на справочную страницу для dirname: http://linux.die.net/man/3/dirname. "Оба dirname () и basename () возвращают указатели на строки с нулевым символом в конце. (Не передавайте эти указатели свободным (3).)"Кроме того, вам, вероятно, не следует делать dir = dirname (dir), поскольку вы потеряли указатель на память, выделенную strdup (выделенная strdup память должна быть передана на освобождение).

1 голос
/ 23 декабря 2011

согласно справочной странице:

ПРЕДОСТОРОЖНОСТИ Функция dirname () возвращает указатель на внутреннюю статическую память, которая будет перезаписана последующие вызовы (каждая функция имеет свое отдельное хранилище).

так что вы, вероятно, не хотите освобождать его. я предполагаю, что это отличается от Linux?

1 голос
/ 23 декабря 2011

Справочная страница для dirname говорит, что вы не должны передавать возвращаемое значение в free(). Но это именно то, что вы делаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...