当我尝试编写一些大数据时,我发现fwrite失败,如下面的代码所示 .
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int size = atoi(argv[1]);
printf("%d\n", size);
FILE* fp = fopen("test", "wb");
char* c = "";
int i = fwrite(c, size, 1, fp);
fclose(fp);
printf("%d\n", i);
return 0;
}
代码被编译成二进制 tw 当我尝试 ./tw 10000
时它运行良好 . 但是当我尝试类似 ./tw 12000
之类的东西时它会失败 . (fwrite()返回0而不是1)这是什么原因?我能以什么方式避免这种情况?
编辑:当我做fwrite(c,1,size,fp)时,它返回8192而不是我给的更大的尺寸 .
第二次编辑:当我写一个运行 size 次的循环,并且每次运行 fwrite(c, 1, 1, fp)
时,它完全正常 . 当 size 太大(如在第一个EDIT中)时,它似乎只写入大约8192个字节 . 我猜有些东西限制 fwrite
一次写入固定大小的字节 .
第3编辑:以上不清楚 . 当空间很大时, space - w_result != 0
的以下内容失败,其中空间由我确定,而w_result是总共写入的对象 .
w_result = 0;
char* empty = malloc(BLOCKSIZE * size(char));
w_result = fwrite(empty, BLOCKSIZE, space, fp);
printf("%d lost\n", space - w_result);
虽然这个工作正常 .
w_result = 0;
char* empty = malloc(BLOCKSIZE * sizeof(char));
for(i = 0; i < space; i ++)
w_result += fwrite(empty, BLOCKSIZE, 1, fp);
printf("%d lost\n", space - w_result);
(每个变量都已声明 . )
我纠正了回答记忆中的一些错误 . 但第一个应该按照你的方式工作 .
4 回答
使用
fwrite(c, size, 1, fp);
,你声明fwrite应该写一个size
大的项目,大的缓冲区c
.c
只是一个指向空字符串的指针 . 它的大小为1.当你告诉fwrite在c
中查找比1个字节更多的数据时,你会得到未定义的行为 . 你不能在c
中写入超过1个字节 .(未定义的行为意味着任何事情都可能发生,当你尝试使用10000的大小而不是12000的大小时它似乎工作正常 . 实现依赖的原因可能是有一些可用的内存,可能是堆栈,开始在
c
和10000字节前,但在例如11000没有内存,你得到一个段错误)您正在读取不属于您的程序的内存(并将其写入文件) .
使用
valgrind
测试您的程序以查看错误 .从那段代码中,看起来你正在尝试将c中的内容(只是一个NULL字节)写入文件指针,并且你正在“大小”这样做 . 事实上,它不会与10000崩溃是巧合 . 你想做什么?
正如其他人所说,代码通过
c
执行无效的内存读取 .一种可能的解决方案是动态分配大小为
size
字节的缓冲区,将其初始化,并将fwrite()
它放到文件中,记住之后释放缓冲区 .请记住检查函数的返回值(例如
fopen()
) .