malloc / free, похоже, получает несколько освобождений - PullRequest
1 голос
/ 28 июня 2011

Я написал функцию для проверки, является ли заданный путь допустимым каталогом Maildir (стандартный Maildir имеет три подпапки «cur», «new» и «tmp»).Функция берет предполагаемый каталог, проверяет эти подпапки и возвращает соответствующим образом.

Я получаю segfault во втором свободном операторе с текущим кодом, и я также получаю ошибку «неверный следующий размер» сКод немного другой организации.Еще более запутанно то, что в одних каталогах он вызывает ошибки только в одном случае, а в других успешно завершается, без видимой причины (хотя он согласован по тем, в каких из них будет происходить ошибка).Со вторым комментарием free () все каталоги с точным форматированием завершаются успешно.

Очевидно, я дважды освобождаюсь.У меня вопрос, почему и как?Если первый free находится внутри условного оператора, и мы возвращаемся сразу после освобождения, мы никогда не получаем второй free.Если мы доберемся до второго бесплатно, это означает, что мы пропустили первый ... верно?

Я понимаю, что в этом контексте это прекрасно, потому что система восстановит память в конце программы, но яМеня больше интересует причина, по которой это происходит, чем просто заставить работать код.Что, если я смотрю на другую ситуацию, функции, вызываемые функциями, вызываемыми функциями и т. Д., И память могут быть проблемой?Разве я не нуждаюсь во втором свободном для восстановления памяти?

int is_valid_folder(char* maildir)
{
 struct stat *buf;
 buf = (struct stat *) malloc(sizeof(struct stat));

char* new = strdup(maildir);
char* cur = strdup(maildir);
char* tmp = strdup(maildir);
strcat (cur, "/cur"); strcat (new, "/new"); strcat (tmp, "/tmp");

if(stat(cur, buf) || stat(tmp, buf) || stat(new, buf))
{
printf("Problem stat-ing one of the cur/new/tmp folders\n");
printf("Error number %d\n", errno);
free(buf);
return 1;
}

free(buf);
return 0; //a valid folder path for this function
}

Ответы [ 3 ]

5 голосов
/ 28 июня 2011

У вас есть несколько переполнений буфера: strdup(), вероятно, выделяет массив char, который достаточно велик, чтобы содержать строку maildir, и вызовы strcat() переполняют массивы. (strcat(), в отличие от strdup(), не создает новый массив char, поэтому вы должны убедиться, что массив, который вы даете, достаточно велик для хранения результирующая строка.)

Кстати, valgrind - ваш друг, когда дело доходит до отслеживания ошибок управления памятью.

1 голос
/ 28 июня 2011

Недостаточно места в повторяющихся строках для объединения.

попробовать:

char* new = (char*)calloc(strlen(maildir) + 5);

и т.д.

0 голосов
/ 28 июня 2011

Я знаю, что вы его получили, но просто в качестве подсказки ... (слишком велик для комментария)

Проверьте возвращаемое значение strdup() для NULL и free() этих указателей, когда выс ними покончено.Если у вас нет памяти, она будет течь (она течет в вашем текущем коде).

Функция strdup () должна возвращать указатель на новую строку, которая является дубликатом строки, на которую указываетпо с1. Возвращенный указатель может быть передан free () .Пустой указатель возвращается, если новая строка не может быть создана.

...