Closed. This question is off-topic. It is not currently accepting answers. Learn more
想改进这个问题吗?Update the question所以堆栈溢出的值小于aa>。
两年前关闭。
似乎有10个问题和(大多数)成功的答案解决了C中错误使用fread()引起的分段错误。也就是说,我有这样一个问题,但还没有找到解决方法。
我有一个二进制文件,其中包含一个int(称为nbins)和一个floats数组(大小为nbins)。当我试图读取这个文件时,它成功地打开并指向文件句柄,但是在读取nbinsint时会出现分段错误。下面是一个简单的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BPATH "/path/to/file"

int main(int agrc, char **argv)
{
    FILE *fd;
    int num;
    char fname[500]={};

    int nbins;
    float *coords;

    num = 5;
    sprintf(fname,"%s/file%d.dat", BPATH, num);

    if(!(fd=fopen(fname,"rb")))
    {
        printf("Can't open file: %s\n\n",fname);
        exit(0);
    }

    printf("Reading input file:\n");
    printf("%p: %s\n", fd, fname);       // prints successfully

    fread(&nbins, sizeof(int), 1, fd);
    printf("nbins = %d", nbins);         // seg faults before this print

    /* EDIT: the above print isn't properly flushed without an \n
     * The seg fault was not caused by the fread(), but the lack of
     * the above print lead to the confusion                         */

    coords = malloc(nbins * sizeof(float));
    fread(coords, sizeof(float), nbins, fd);

    fclose(fd);
    free(coords);

    return(0);
}

文件是用以下格式创建的:
int nbins[1];
nbins[0] = 5;                          // this 5 is just an example...
fwrite(nbins, sizeof(int), 1, file_ptr);
fwrite(coords, sizeof(float), nbins[0], file_ptr);

我也尝试过使用:
int *nbins = malloc(sizeof(int));
fread(nbins, sizeof(int), 1, fd);

但这并没有解决问题。
该文件确实存在,可读性很好;我可以使用Python,使用NumPy的

最佳答案

您可能已经undefined behavior,出现以下情况:
int nbins;无法初始化,因此它包含垃圾数据,可能是非常大的数量。
nbins未经测试,因此可能会失败,并使fread(&nbins, sizeof(int), 1, fd);保持未初始化状态。阅读fread
nbins没有printf("nbins = %d", nbins);并且后面没有显式的\n所以不要显示任何内容(因为fflush通常是行缓冲的)。
stdout将需要大量内存,因此将失败并在coords = malloc(nbins * sizeof(float));中获取NULL
coords写入fread(coords, sizeof(float), nbins, fd);指针,导致分段冲突,因为UB
你真幸运。事情可能是worse(我们都可能被黑洞湮灭)。你也可以尝试一些nasal demons,甚至更糟的是,有一些执行似乎是有效的。
下次,请避开UB。我不想消失在黑洞里,所以请容忍我们。
顺便说一句,如果使用GCC,编译时会显示所有警告和调试信息:NULL。它会警告你的。如果没有,您将在gcc -Wall -Wextra -g调试器下获得SEGV。在Linux上,valgrindstrace也可以起到帮助作用。
注意无用的初始化(例如,在您的情况下显式的gdb)在实践中不会造成损害。优化编译器可能会删除它们,如果它们是无用的(当它们不是无用的,在您的情况下,它们是非常快的)。
强制读取
拉特纳的博客:What Every C Programmer should know about UB。相关概念:As-if rule
还要阅读您正在使用的每个函数的文档(甚至与int nbins = 0;一样常见)。

关于c - 二进制文件中存储的int的fread()不成功,出现段错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46526430/

10-10 07:58