我很难弄清楚为什么我的程序不能将超过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字符串以及malloccalloc的内容。
在原来的mainttt中,指向调用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/

10-12 14:04