C 将文件读入缓冲区,但程序在调用fseek后在fread崩溃
我想把文件读入缓冲区。我在C 将文件读入缓冲区,但程序在调用fseek后在fread崩溃,c,file-io,segmentation-fault,fread,fseek,C,File Io,Segmentation Fault,Fread,Fseek,我想把文件读入缓冲区。我在fread()处遇到分段错误。看起来ftell()返回了正确的大小。但后来事情就出了问题。将fseek()修改f?为什么fread()不起作用 int pk_load_file( const char *filename ) { FILE *f; int size; unsigned char *buf; if( ( f = fopen( filename, "rb" ) ) == NULL ) return -1;
fread()
处遇到分段错误。看起来ftell()
返回了正确的大小。但后来事情就出了问题。将fseek()
修改f
?为什么fread()
不起作用
int pk_load_file( const char *filename )
{
FILE *f;
int size;
unsigned char *buf;
if( ( f = fopen( filename, "rb" ) ) == NULL )
return -1;
fseek( f, 0, SEEK_END );
if( ( size = ftell( f ) ) == -1 )
{
fclose( f );
return -2;
}
fseek( f, 0, SEEK_SET );
if( fread( buf, 1, size, f ) != size )
{
fclose( f );
return -3;
}
fclose( f );
return( 0 );
}
这里的问题是
if( fread( buf, 1, size, f ) != size )
在上述情况下,您使用的是buf
uninitialized。在使用之前,您需要将内存分配给buf
由于未初始化,buf
可以指向进程无法访问的任何内存位置。因此,尝试访问buf
指向的内存会调用
分割错误是一种副作用
解决方案:您可以使用和系列将内存分配给buf
。正确的代码:
#include <stdio.h>
#include <stdlib.h>
int pk_load_file( const char *filename ) {
FILE *f;
int size;
unsigned char *buf;
if ((f = fopen(filename, "rb")) == NULL) {
return -1;
}
fseek(f, 0, SEEK_END);
if ((size = ftell(f)) == -1) {
fclose(f);
return -2;
}
buf = malloc(size); // here is the magic. you need to allocate "size" bytes
if (buf == NULL) {
fclose(f);
return -3;
}
fseek(f, 0, SEEK_SET);
if (fread(buf, 1, size, f) != size) {
fclose(f);
return -4;
}
fclose(f);
return 0;
}
#包括
#包括
int pk_加载_文件(常量字符*文件名){
文件*f;
整数大小;
无符号字符*buf;
if((f=fopen(文件名,“rb”))==NULL){
返回-1;
}
fseek(f,0,SEEK_END);
如果((大小=ftell(f))=-1){
fclose(f);
返回-2;
}
buf=malloc(size);//这里有个神奇的地方。你需要分配“size”字节
如果(buf==NULL){
fclose(f);
返回-3;
}
fseek(f,0,SEEK_集);
if(fread(buf,1,尺寸,f)!=尺寸){
fclose(f);
返回-4;
}
fclose(f);
返回0;
}
如上所述,它给出了未定义的行为,所以要么使用动态分配,要么将其声明为数组
#define MAX_LENGTH 1024
unsigned char buf[MAX_LENGTH];
然后将其传递给
fread()
@rakeb.void为什么<代码>fseek(f,0,SEEK_SET)代码>支持它做什么?您应该检查大小是否超过最大长度,并正确处理该情况。@Leandros是的,应该检查该条件。不要使用fseek()/ftell()
计算文件大小,尤其是在二进制模式下。根据C标准():“二进制流不需要有意义地支持带有whence值SEEK_END的fseek调用”。另请参见:fread按原样读取数据,不添加任何内容。编辑您的原始代码并展示如何尝试释放buf。
#define MAX_LENGTH 1024
unsigned char buf[MAX_LENGTH];