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];