当我尝试编写一些大数据时,我发现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而不是我给的更大的尺寸。
第二次编辑:当我编写一个运行大小次并且每次都fwrite(c, 1, 1, fp)
的循环时,它完全正常。
当 size 过大时(如在第一个EDIT中)它似乎只写了大约8192个字节。
我猜有些东西限制fwrite
一次写入固定大小的字节。
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);
(已声明每个变量。)
我纠正了所记录的答案中的一些错误。但第一个应该按照你的意思运作。
答案 0 :(得分:2)
您正在读取不属于您的程序的内存(并将其写入文件)。
使用valgrind
测试您的程序以查看错误。
答案 1 :(得分:2)
使用fwrite(c, size, 1, fp);
,您声明fwrite应该在缓冲区size
中写出c
大的{1}}项。
c
只是一个指向空字符串的指针。它的大小为1.当你告诉fwrite寻找比c
中的1个字节更多的数据时,你会得到未定义的行为。你不能从c
写入超过1个字节。
(未定义的行为意味着任何事情都可能发生,当你尝试使用10000的大小而不是12000的大小时,它似乎工作正常。实现依赖的原因很可能是有一些可用的内存,也许是堆栈,从c
开始,前面是10000字节,但是例如11000没有内存,你会得到一个段错误)
答案 2 :(得分:1)
从那段代码中,看起来你正在尝试将c中的内容(只是一个NULL字节)写入文件指针,并且你正在“大小”这样做。事实上,它不会与10000崩溃是巧合。你想做什么?
答案 3 :(得分:1)
正如其他人所说,代码通过c
执行无效的内存读取。
一种可能的解决方案是动态分配大小为size
个字节的缓冲区,将其初始化,然后fwrite()
到文件中,记住之后释放缓冲区。
请记住检查函数的返回值(例如fopen()
)。