Pau*_*aul 59 c linux memory-management
如果buf是已malloc()分配的字符缓冲区,是否free(buf)设置/重置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.
free()的linux手册页也是等的手册页malloc().它提到malloc()设置errno,但不是free().
用于释放动态内存的GNU C Library手册页没有提到free()是否设置了errno.
所以我写了一个简短的程序来强制写入错误,这样我就可以看到free()是否重置错误,而不是.我想知道我是否应该依赖这个结果以及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,"%s\n", "Hello, World!");
  FILE *badfile;
  badfile = fopen("/dev/null","r");
  fputs(buf, badfile);
  free(buf);
  printf("%d\n", errno);
  printf("%s\n", strerror(errno));
}
San*_*ker 49
POSIX没有定义free设置errno(尽管POSIX目前不禁止它,因此实现可能会这样做 - 请参阅@ ArjunShankar的答案以获取更多详细信息).但这与你的担忧并不相关.
您检查错误的方式不正确.你应该检查它的返回值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;
Arj*_*kar 36
今天free可能会设置POSIX兼容errno ,但未来这种情况会有所改善.细节:
errno陈述如下:此卷POSIX.1-2008中的任何功能都不应将errno设置为0.除非该函数的描述指定不应修改errno,否则未指定成功调用函数后的errno设置.
free本身并没有规定什么free用呢errno.这意味着兼容的free实现永远不会重置errno为0.但它可能会也可能不会将其设置为非零值.
但是,规范的第8版(正在进行的工作)将要求free特别保证errno在传递有效输入时不会设置.
glibc已经准备好遵守这一新要求.
Vla*_*cow 16
在C标准errno的描述中没有任何说法free.所以你可能不会依赖这个功能.
根据C标准(7.5错误<errno.h>)
3 ...如果在本国际标准的功能描述中没有记录errno的使用,则可以通过库函数调用将errno的值设置为非零值,无论是否存在错误.
并且在C标准errno的描述中没有记载使用,free正如我上面已经说过的那样.
mol*_*ilo 13
如果引用没有说函数errno在失败时返回错误代码,则不会.  
设置errno为错误代码的函数(几乎)总是以errno包含当前错误代码的另一种方式发出信号- 内存分配函数返回NULL,许多其他函数返回零或负数,依此类推.
如果这些功能errno成功,则无需以任何方式进行修改,通常也不需要.
你通常无法检查errno以确定是否出了问题; 它仅用于在您知道出现错误后检索更多信息.
最终规则的一个例外是strto{l, d, ul}家庭,但第一段也是如此.
它们也不一定设置,errno除非它们失败,所以你需要先清除它,否则它可能包含陈旧的错误代码.