malloc基于现有文件的文件缓冲区大小

时间:2012-04-13 09:16:33

标签: c malloc stdio fseek

在我的项目中,我需要将共享文件复制到一个名为share的目录中。我的想法是使用fgets和fputs复制此文件的包含:

FILE *fp;
int size;
char *fileBuff

fseek(fp,0,SEEK_END );
size=ftell(fp);
printf("Size of %s: %d bytes.\n",path,size); // print correct size 
fileBuff=malloc(size); // mallocate the file buffer
printf("\nsize of file buffer is %d",sizeof(fileBuff)); //always print 4!!
while(!feof(fp)){
    fgets(fileBuff,size,fp); // put into file buffer

}
printf("\nsize of file buffer is %d",sizeof(fileBuff)); // also print 4!!

但是,文件缓冲区无法进行mallocated,此文件缓冲区的大小始终为4.会发生什么?

更新: 似乎有一些误解。 sizeof()如果只是为了检查文件缓冲区中是否存在任何东西。我尝试strlen(fileBuff),它总是给我1个。

5 个答案:

答案 0 :(得分:4)

这是错误的:sizeof(fileBuff)。这将是指针的大小,在系统上为4。

您不能使用sizeof来“提取”malloc()返回的内存块的大小。您不能使用任何来提取该大小,在(标准)C中根本不可能。您需要使用size值,即malloc()的参数。

另外,ftell()会返回long,而不是int,而malloc()strlen()都会失败,并且您需要考虑各种I / O调用。

在我看来,使用文件大小的缓冲区做一个简单的复制不是一个好主意;使用“合理”缓冲区(其确切的最佳大小取决于很多因素)然后在循环中重复读写对,直到您在整个文件中流式传输为止。

更新关于您的代码的更多要点:

  1. 您谈到使用sizeof,但代码也在fread()之后显示sizeof
  2. 您谈到使用sizeof“检查”缓冲区中是否有任何内容,这是不可能的;任何带有malloc()的表达式总是在编译时 1 进行求值,它不能用于检查这样的动态事物。而且,您再次无法使用它来计算strlen()返回的内存块的大小。
  3. 在保存文件数据的缓冲区上使用strlen()仅在文件是二进制文件并且在其最后位置包含“\ 0”时才能可靠地工作,否则您将有一个未终止的字符串并且malloc()可能会调用未定义的行为。
  4. 正如我所说,你需要检查NULL是否返回{{1}},如果它未能分配所请求的内存块,它将会这样做。
  5. 1 除了C99中的flexible arrays,但我们忽略它。

答案 1 :(得分:2)

99位开发人员现在回答您正在使用指针的大小。我甚至不必查看代码。

答案 2 :(得分:0)

(32位)平台上指针(char *)的大小始终为4。

您不能使用sizeof来确定为缓冲区分配了多少内存。

要检查指针是否已分配,请检查malloc()的返回值:

fileBuff = malloc(size);

if (fileBuff == 0) {
   fprintf(stderr, "Error allocating %d bytes.\n", size);
   abort();
}

答案 3 :(得分:0)

sizeof编译时进行评估,因为您要求sizeof filebuf char*编译器计算它是malloc 4个字节(因为指针的大小是你平台的4个字节)并打印出来。您所做的sizeof与{{1}}无关。

答案 4 :(得分:0)

除了不正确使用 sizeof()之外,你可以考虑另外两个想法:

如果只是复制文件:不要试图重新发明轮子,只需使用 system()功能并调用专为此设计的操作系统程序( cp 在unix上,在DOS / Windows上复制

如果它是出于培训目的而你坚持自己这样做:不要尝试读取整个文件然后再写出来,而是按块读取和写入块。使用大缓冲区大小只会导致CPU缓存变得毫无价值。通常匹配文件系统缓冲区大小或它的一小部分是一个goot chunk大小,所以伪代码应该如下所示:

open input file for reading
open output file for writing
as long as read from input file BUFSIZE bytes and read bytes > 0
     do write read data to output file
close input file
close output file

(并且不要忘记在每次调用I / O例程后检查I / O错误!)

最后一点:不要使用 fgets(),除非您确定它始终是纯文本文件。如果你选择使用 fread()/ fwrite(),你就会保存,即使它是一个二进制文件(而且它也更快)。