Устанавливает ли free () errno?
если buf это malloc() выделенный буфер типа char, делает free(buf) set / reset errno?
допустим я хочу записать буфер в файл, а затем освободить его, как я не нужна.
предположим, что политика ошибок для кода должна возвращать -1 при ошибке.
это правильный способ записать буфер и проверить ошибку без утечки памяти?
fputs(buf, somefile);
free(buf);
if (errno) return -1;
или мне нужно рассмотреть возможность свободной установки errno, как в...
fputs(buf, somefile);
if (errno){
free(buf);
return -1;
}
free(buf);
или, о ужас,
do {
fputs(buf, somefile);
int save_errno = errno;
free(buf);
errno = save_errno;
if (errno) return -1;
} while(0);
где использование блока позволяет локальному save_errno существовать в различных местах, если это необходимо повторно использовать.
все это, казалось бы, зависит от того, устанавливает ли free() errno.
The Linux man page бесплатно () также на man-страницах malloc() и т. д. Он упоминает malloc() установка errno, но не free().
The библиотека GNU C ручная страница для освобождения динамической памяти не упоминает ли free () устанавливает errno.
поэтому я написал короткую программу, чтобы заставить ошибку записи, чтобы я мог увидеть, если free() reset errno, и это не так. Мне интересно, должен ли я полагаться на этот результат и тот факт, что free() настолько важен, что "конечно, он не устанавливает errno."
# See if free() resets errno on a bad write
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
char * buf = malloc(256);
snprintf(buf,256,"%sn", "Hello, World!");
FILE *badfile;
badfile = fopen("/dev/null","r");
fputs(buf, badfile);
free(buf);
printf("%dn", errno);
printf("%sn", strerror(errno));
}
5 ответов:
POSIX не определяет
freeустановитьerrno(хотя POSIX в настоящее время не запрещает это, поэтому реализация может сделать это - см. @ArjunShankar это!--8--> для более подробной информации). Но это не имеет никакого отношения к вашей проблеме.то, как вы проверяете ошибки, неверно. Вы должны проверить возвращаемое значение
fputs, и проверить, если это меньше, чем0. Если это так, то вы можете увидетьerrnoчтобы узнать, что вызвало сбой, но это необязательно (и должно быть сделано перед вызовом каких-либо дополнительных функций).Итак, что-то вроде этого должно сделать трюк :
int result = fputs(buf, somefile); /* optionally read errno here if result < 0 (before the free call) */ free(buf); return (result < 0) ? -1 : 0;
POSIX совместимый
freeможетerrnoно в будущем это изменится к лучшему. Подробности:
- The Вопрос 7 Спецификаций Открытой Группы Низкопробный определение
errnoуказано следующее:нет функции в этом томе POSIX.1-2008 устанавливает errno в 0. Значение errno после успешного вызова функции не определено, если только описание этой функции указывает, что errno не должен быть изменен.
- определение
freeсам не уточняет чтоfreeсerrno.что соответствует
freeреализация никогда не будет сброшенerrnoк 0. Но он может или не может установить его в ненулевое значение.однако, выпуск 8 (незавершенное производство) спецификации будут требуются
freeв частности, гарантировать, что он не будет ставитьerrnoпри передаче допустимого ввода.glibc уже готовится придерживаться этого нового требования.
там ничего не сказано про
errnoв описанииfreeв стандарте C. Поэтому вы не можете полагаться на эту функцию.согласно стандарту C (7.5 ошибки
<errno.h>)3...Значение errno может быть установлено в ненулевое с помощью вызова библиотечной функции независимо от наличия ошибки, при условии использования errno не задокументировано в описании функции в этом международный стандарт.
и использование
errnoне задокументировано в описанииfreeв стандарте C как я уже сказал выше.
если ссылка не говорят, что функция возвращает код ошибки в
errnoна провал, это не будет.функции, которые выделяют
errnoкоду ошибки (почти) всегда сигнализируют по-другому, чтоerrnoсодержит текущий код ошибки - функции выделения памяти возвращаютNULLмногие другие функции возвращают ноль или отрицательное число, и так далее.
Такие функции не требуется изменятьerrnoв любом случае, если они преуспеют, и обычно не надо.вы обычно не можете проверить
errnoчтобы определить, что-то пошло не так; он предназначен только для получения дополнительной информации, как только вы знаете, что произошла ошибка.одним исключением из последнего правила является
strto{l, d, ul}семья, но первый абзац верен и для них.
И они не обязательноerrnoза исключением случаев, когда они терпят неудачу, поэтому вам нужно сначала очистить его, или он может содержать устаревший код ошибки.
вы можете использовать RAII для освобождения памяти malloced и проверить возвращаемое значение fputs. Это будет код благодати.
//if malloc successfully AutoFree af(buf); if (fputs(buf, somefile)) { LOG("something err:%s", strerror(errno)); } return 0;
Comments