【问题标题】:read a file into a buffer, but program crashes at fread after calling fseek将文件读入缓冲区,但调用 fseek 后程序在 fread 处崩溃
【发布时间】:2015-07-24 06:38:25
【问题描述】:

我想将文件读入缓冲区。我在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 );
 }

【问题讨论】:

标签: c file-io segmentation-fault fread fseek


【解决方案1】:

这里的问题是

if( fread( buf, 1, size, f ) != size )

在上述情况下,您使用的是未初始化的buf。使用前需要给buf分配内存。

由于未初始化,buf 可以指向进程无法访问的任何内存位置。因此,尝试访问buf 指向的内存会调用undefined behaviour

分段错误是副作用之一。

解决方案:您可以使用malloc() 和family 为buf 分配内存。

【讨论】:

  • @rakeb.void 为什么? fseek( f, 0, SEEK_SET ); 它应该做什么?
【解决方案2】:

正确代码:

#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;
}

【讨论】:

  • fread 按“原样”读取数据,不添加任何内容。编辑您的原始代码并展示您如何尝试释放 buf。
【解决方案3】:
 unsigned char *buf;

如上所述,它给出了未定义的行为,因此要么使用动态分配,要么将其声明为数组,

 #define  MAX_LENGTH 1024
 unsigned char buf[MAX_LENGTH];

然后将其传递给fread()

【讨论】:

  • 您应该检查大小是否超过最大长度,并正确处理案例。
  • @Leandros 是的,应该检查那个条件。
猜你喜欢
  • 1970-01-01
  • 2018-10-02
  • 1970-01-01
  • 2016-06-28
  • 1970-01-01
  • 2012-02-16
  • 2018-07-21
  • 2021-07-21
  • 1970-01-01
相关资源
最近更新 更多