我希望你的帮助应该很容易,我不知道为什么它不起作用。我想从bin中读取第一个数据,我知道它是一个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);
它应该是指针的东西,但我看不清楚。
答案 0 :(得分:9)
变化:
int *data;
至int data;
printf("Data read is: %d\n",*data);
至printf("Data read is: %d\n",data);
您正在将int
读入指针,然后尝试取消引用指针(指针具有无效的值)。
答案 1 :(得分:3)
您没有为data
分配任何内存,并且在第一个示例代码中您没有正确使用指针。这是可行的替代方案:
int data;
然后你会像这样使用它:
fread(&data,sizeof(int),1, ptr_myfile);
在您的原始代码中,您在此处将int
写入指针:
fread(&data,sizeof(int),1, ptr_myfile) ;
然后此*data
将取消引用无效指针。在另一种情况下:
fread(data,sizeof(int),1, ptr_myfile);
您将使用没有分配内存的指针。
答案 2 :(得分:2)
您正在传递未分配指针的地址。从*
移除data
:
int data;
...
fread(&data, sizeof(int), 1, ptr_myfile);
答案 3 :(得分:1)
你正在思考指针的问题。函数fread()
需要知道存储它读取的数据的地址,因此它会传递一个指针。这并不意味着fread
使用的缓冲区应该是一个指针,只需fread
需要指向该缓冲区的指针。
所以你的第一个错误就是写int *data;
而你只是int data;
。您说要读取的数据元素是int
,因此您只需声明int
来保存它。
您通过将指针传递给实际分配的有效内存(即fread
)正确调用&data
来读取数据,避免了将未初始化的指针传递给您之前声明的整数的不同初学者陷阱。
您在*data
的通话中写printf
会导致实际错误。 *
运算符使用指针并取消引用它。换句话说,它假定指针指向某个东西,并检索该值。但是,当被解除引用的指针未指向任何有效的某事时,您就会遇到问题。
这是你幸运的地方。然后,*
运算符将您从文件中读取的值视为内存中的地址,但恰好是一个不属于您的进程可访问的内存的地址,这导致系统注意到使用分段错误停止该过程。因此,您立即了解到代码中存在错误。
如果你不幸运,那么当你被视为内存地址时,你从文件中读取的整数可能是你进程中已存在的东西的地址。你不会导致分段错误,你会为printf
产生一个奇怪的答案而感到困惑。
现在假设您从不受信任的来源读取值并将其视为任意地址。攻击者可以使用该错误来了解您的程序。更糟糕的是,如果您已经写入该指针引用的内存,攻击者可以想象地改变您的程序的行为。
最后一点,请注意,只要该文件永远不会传输到其他系统,读取和写入int
(或任何其他数据类型)是安全可接受的。并非所有系统都同意甚至最简单的定义,例如int占用的字节数(您使用sizeof(int)
正确处理的字节数,但是不允许以允许使用具有不同整数的系统交换文件的方式) size),甚至是内存中那些字节的顺序。正确解决这些问题是一个很大的主题。