fread bin文件中的一个int在C中给了我一个分段错误

fread bin文件中的一个int在C中给了我一个分段错误,c,fread,C,Fread,我需要你的帮助,在一些应该是容易的,我不知道为什么它不工作。我想从一个箱子中读取第一个数据,我知道它是一个int。我正在使用以下代码部分,但我遇到了一个分段错误: int main(int argc, char **argv) { int *data; /*opening file*/ FILE *ptr_myfile; ptr_myfile=fopen(myfile.bin","rb"); if (!ptr

我需要你的帮助,在一些应该是容易的,我不知道为什么它不工作。我想从一个箱子中读取第一个数据,我知道它是一个int。我正在使用以下代码部分,但我遇到了一个分段错误:

int main(int argc, char **argv)
    {
        int *data;
        /*opening file*/
        FILE *ptr_myfile;
        ptr_myfile=fopen(myfile.bin","rb");
        if (!ptr_myfile)
        {
            printf("Unable to open file!\n");
            return 1;
        }
        /*input file opened*/
        printf("I will read the first 32-bit number\n");
        /*will read the first 32 bit number*/
        fread(&data,sizeof(int),1, ptr_myfile);
        printf("Data read is: %d\n",*data);     

        fclose(ptr_myfile);
        return 0;
    }
我也试着这样称呼它:

fread(data,sizeof(int),1, ptr_myfile);
它应该是指针的东西,但我看不出是什么。

更改:

  • int*数据
    int数据
  • printf(“读取的数据为:%d\n”,*数据)
    printf(“读取的数据为:%d\n”,数据)

您正在将
int
读入一个指针,然后尝试取消对该指针的引用(该指针的值作为指针没有意义)。

您没有为
数据分配任何内存,在第一个示例代码中,您没有正确使用指针。这是一个可行的替代方案:

int data;
然后你会这样使用它:

fread(&data,sizeof(int),1, ptr_myfile);
在原始代码中,您正在将
int
写入指针:

fread(&data,sizeof(int),1, ptr_myfile) ;
然后此
*数据将取消对无效指针的引用。在另一种情况下:

fread(data,sizeof(int),1, ptr_myfile);

您将使用未分配内存的指针。

您正在传递未分配指针的地址。从
数据中删除
*

int data;
...
fread(&data, sizeof(int), 1, ptr_myfile);

你对指针的问题想得太多了。函数
fread()
需要知道它读取的数据的存储地址,因此会向它传递一个指针。这并不意味着
fread
使用的缓冲区应该是指针,只是
fread
需要指向该缓冲区的指针

因此,您的第一个错误是写入
int*数据你真正的意思是
int数据。您说要读取的数据元素是
int
,因此您只需声明一个
int
来保存它

您正确地调用了
fread
,通过将指针传递到实际分配的有效内存(即
&data
)来读取数据,从而避免了将未初始化的指针传递到前面声明的整数的不同初学者陷阱

实际错误是由于在调用
printf
时写入
*数据
引起的。
*
运算符获取指针并取消对它的引用。换句话说,它假定指针指向某个对象,并检索该值。但是,当被取消引用的指针没有指向任何有效的内容时,您就有问题了

这就是你幸运的地方。然后,
*
操作符将从文件中读取的值作为内存中的地址处理,但碰巧是一个地址,它不是进程可访问内存的一部分,这导致系统注意到并由于分段错误而停止进程。因此,您立即了解到代码中存在错误

如果您运气不好,那么当您将从文件中读取的整数作为内存地址时,它可能是进程中已经存在的某个对象的地址。您不会导致分段错误,您会被
printf
为什么会产生奇怪的答案所迷惑

现在想象一下,如果您从不受信任的源读取一个值,并将其视为任意地址。攻击者可以利用该错误了解有关您的程序的信息。更糟糕的是,如果您已写入该指针所引用的内存,攻击者可能会改变程序的行为


最后,请注意,只要文件永远不会传输到不同的系统,读取和写入
int
(或任何其他数据类型)都是安全和可接受的。并非所有系统都同意最简单的定义,如int所占用的字节数(您确实使用
sizeof(int)
正确处理了该定义,但不允许与具有不同整数大小的系统交换文件),甚至不同意内存中这些字节的顺序。正确解决这些问题是一个大课题。

int*数据-->
int数据您的代码
fread(&data,sizeof(int),1,ptr\u myfile)中有两行相同的2-3行。难道这是注定的吗?