【发布时间】:2021-05-30 11:56:53
【问题描述】:
- POSIX 是否保证在 open_memstream 的 FILE 写入操作中设置了 ferror?
- 如果 FILE 是使用 open_memstream 创建的,如何检查 FILE 操作的内存不足情况?
我曾经假设如果内部重新分配失败并且可以使用 ferror 获得错误条件,则应该在流上设置错误,但以下使用 glibc 2.31 的测试表明它没有这样做(Linux overcommit_memory 已禁用) :
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
static char chunk[1024] = {1};
int main(void) {
size_t sz = 0;
char *s = NULL;
FILE *sf = open_memstream(&s, &sz);
if (!sf) {
fprintf(stderr, "%d: ERROR open_memstream failed: %s", (int)__LINE__, strerror(errno));
return -1;
}
for (;;) {
size_t new_n = fwrite(chunk, sizeof chunk, 1, sf);
if (ferror(sf))
fprintf(stderr, "%d: ERROR ferror(sf): %s\n", (int)__LINE__, strerror(errno));
if (new_n == 0)
break;
}
if (fflush(sf))
fprintf(stderr, "%d: ERROR fflush(sf)\n", (int)__LINE__);
if (ferror(sf))
fprintf(stderr, "%d: ERROR ferror(sf)\n", (int)__LINE__);
fprintf(stderr, "%d: writing done %zu\n", (int)__LINE__, sz);
fclose(sf);
free(s);
return 0;
}
user@ws:~$ ./a.out
30: writing done 4347395995
glibc 问题单: https://sourceware.org/bugzilla/show_bug.cgi?id=26573
【问题讨论】:
-
Linux overcommit_memory is disabled它在这里做什么?memstream完全是用户空间实现——不涉及内核。int new_n = fwritefwrite返回一个size_t。(int)__LINE__为什么要转换为int? -
@KamilCuk 1. 但它会重新分配 - 取决于在 overcommit_memory 中设置的内容,在 oom 上,linux 进程将被杀死或从调用中返回 NULL 指针。 2. + 3. LINE 保证为整型常量,但不保证类型。