我很难弄清楚为什么我的程序不能将超过2GB的数据保存到一个文件中。我不知道这是编程还是环境(OS)问题。这是我的源代码:
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <math.h>
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*-------------------------------------*/
//for file mapping in Linux
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/time.h>
#include<sys/mman.h>
#include<sys/types.h>
/*-------------------------------------*/
#define PERMS 0600
#define NEW(type) (type *) malloc(sizeof(type))
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
void write_result(char *filename, char *data, long long length){
int fd, fq;
fd = open(filename, O_RDWR|O_CREAT|O_LARGEFILE, 0644);
if (fd < 0) {
perror(filename);
return -1;
}
if (ftruncate(fd, length) < 0)
{
printf("[%d]-ftruncate64 error: %s/n", errno, strerror(errno));
close(fd);
return 0;
}
fq = write (fd, data,length);
close(fd);
return;
}
main()
{
long long offset = 3000000000; // 3GB
char * ttt;
ttt = (char *)malloc(sizeof(char) *offset);
printf("length->%lld\n",strlen(ttt)); // length=0
memset (ttt,1,offset);
printf("length->%lld\n",strlen(ttt)); // length=3GB
write_result("test.big",ttt,offset);
return 1;
}
根据我的测试,这个程序可以生成一个大于2GB的文件,并且可以分配这么大的内存。
当我试图将数据写入文件时,奇怪的事情发生了。我检查了一下文件,它是空的,应该是1。
有人能帮我吗?
最佳答案
您需要阅读更多关于C字符串以及malloc
和calloc
的内容。
在原来的main
ttt
中,指向调用malloc
时内存中的任何垃圾。这意味着nul终止符(C字符串的结束标记,二进制0)可以位于malloc
返回的垃圾中的任何位置。
另外,由于malloc
没有触及分配的内存的每个字节(而且您要求很多),因此可能会得到稀疏的内存,这意味着在读或写之前,内存实际上是不可用的。calloc
分配并用0填充已分配的内存。由于这个原因,它更容易失败(它涉及到分配的每个字节,因此如果操作系统保持分配稀疏,那么在calloc
填满它之后,它就不会稀疏了)
这是您的代码和上述问题的修复。
您还应该始终检查write
的返回值并作出相应的反应。我就留给你了。。。
主()
{
长长偏移量=3000000000;//3GB
字符*ttt;
//ttt=(char*)malloc(sizeof(char)*偏移量);
ttt=(char*)calloc(sizeof(char),offset);///而不是malloc(…)
如果(!ttt公司)
{
puts(“calloc失败了,现在再见!”);
退出(87);
}
printf(“length->%lld\n”,strlen(ttt));//length=0(如果calloc没有失败,现在可以按预期工作)
memset(ttt,1,偏移量);
ttt[offset-1]=0;//现在它以nul结尾,下面的printf将工作
printf(“长度->%lld\n”,strlen(ttt));//length=3GB
写入结果(“test.big”,ttt,offset);
返回1;
}
Linux大师注意。。。我知道稀疏可能不是正确的术语。如果我错了,请纠正我,因为我已经有一段时间没有埋头于Linux的细节了。:)
关于c - 为什么我的程序无法将大量(> 2GB)保存到文件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11169202/