[英]Malloc the size of file buffer base on an existing file
在我的项目中,我需要将共享文件复制到一个名为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!!
但是,不能分配文件缓冲区,该文件缓冲区的大小始终为4.。会发生什么?
更新:似乎有些误会。 sizeof()是否仅用于检查文件缓冲区中是否存储了任何内容。 我确实尝试了strlen(fileBuff),它总是给我1,
这是错误的: sizeof(fileBuff)
。 这将是指针的大小,在您的系统上为4。
您不能使用sizeof
来“提取” malloc()
返回的malloc()
块的大小。 您不能使用任何东西来提取该大小,在(标准)C语言中根本不可能。您需要使用size
值,即malloc()
的参数。
同样, ftell()
返回long
,而不是int
并且malloc()
和各种I / O调用都可能失败,您需要考虑到这一点。
我认为,使用文件大小的缓冲区进行简单复制不是一个好主意。 最好使用“合理的”缓冲区(其确切的最佳大小取决于很多因素),然后在循环中进行重复的读写对,直到流过整个文件为止。
更新有关您的代码的其他要点:
strlen()
但是代码也在fread()
之后显示sizeof
。 sizeof
来“检查”缓冲区中是否有任何东西,这是不可能的; 任何带有sizeof
表达式总是在编译时1进行求值,它不能用于检查像这样的动态事物。 同样,您不能使用它来计算malloc()
返回的malloc()
块的大小。 strlen()
仅在文件为二进制文件且最后一个位置包含'\\ 0'时才能可靠地工作,否则,您将拥有一个不终止的字符串,并且strlen()
可能会调用未定义的行为。 malloc()
返回NULL
,如果它未能分配所请求的内存块,它将执行此操作。 1除了C99中的灵活数组外,让我们忽略它。
现在有99位开发人员将回答您正在使用指针大小。 我什至不必看代码。
您的(32位)平台上的指针( char *
)的大小始终为4。
您不能使用sizeof
来确定为缓冲区分配了多少内存。
要检查指针是否已分配,请检查malloc()
的返回值:
fileBuff = malloc(size);
if (fileBuff == 0) {
fprintf(stderr, "Error allocating %d bytes.\n", size);
abort();
}
sizeof
是在编译时求值的,因为您要查询filebuf
sizeof
,而char*
编译器会计算它的大小为4个字节(因为指针的大小为平台的4个字节),然后打印出来。 您执行的malloc
与sizeof
无关。
除了不正确地使用sizeof()之外,您还可以考虑以下两种想法:
如果只是复制文件:不要尝试重新发明轮子,而只需使用system()函数并调用为此目的设计的OS程序(Unix上为cp ,在DOS / Windows上为复制 )。
如果是出于培训目的,因此您坚持要自己做:不要尝试读入整个文件,然后再次将其写出,而是逐块读取和写入。 使用大缓冲区只会导致CPU缓存变得毫无价值。 通常与文件系统缓冲区大小匹配或仅占其很小一部分的就是goot块大小,因此伪代码应类似于:
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() ,即使它是二进制文件(而且速度也更快),您将被保存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.