我提前为我缺乏知识而道歉,因为我是本地FORTRAN程序员。我得到了一些c代码来调试哪个摄取二进制文件并将其解析为一个输入文件,其中包含我正在使用的Fortran程序的几百条记录(准确地说是871)。问题是这些输入二进制文件和相关的c代码是在Windows环境中创建的。解析器读取二进制文件直到它到达文件末尾:
SAGE_Lvl0_Packet GetNextPacket()
{
int i;
SAGE_Lvl0_Packet inpkt;
WORD rdbuf[128];
memset(rdbuf,0,sizeof(rdbuf));
fprintf(stdout,"Nbytes: %u\n",Nbytes);//returns 224
if((i = fread(rdbuf,Nbytes,1,Fp)) != 1)
FileEnd = 1;
else
{
if(FileType == 0)
memcpy(&(inpkt.CCSDS),rdbuf,Nbytes);
else
memcpy(&inpkt,rdbuf,Nbytes);
memcpy(&CurrentPacket,&inpkt,sizeof(inpkt));
}
return inpkt;
}
因此,当代码到达数据包872时,此代码段应返回FileEnd = 1.相反,解析器会尝试从文件末尾(接近)读取大量数据。我认为这会导致程序崩溃(至少它会在Fortran中崩溃。会不会开始读取内存的下一部分?)幸运的是,稍后在代码中有一个CRC可以捕获解析器isn'读取正确的数据并优雅地退出。
我认为问题源于二进制缓冲区大小和Windows二进制文件中的值大于/不同于Linux中的二进制缓冲区大小和值。如果是这种情况,有没有一种简单的方法可以在c或Linux中将Windows二进制文件转换为Linux?如果我的假设错了,那么也许我需要更多地查看代码。顺便说一句,WORD是一个无符号短整数,而一个SAGE_Lvl0_Packet是一个3层结构,共有106个WORD。
答案 0 :(得分:1)
我认为这里最大的问题是,当fread()
表示文件结束时,FileEnd
标志被设置,但该函数仍然最终返回一个(无效的)归零数据包。不是特别强大的设计。我假设调用者应该在尝试使用刚才返回的数据包之前检查FileEnd
,但由于没有显示,所以很可能是错误的假设。
此外,不知道数据包的外观,无法判断各种memcpy()
调用是否正确。要求memcpy()
将224个字节复制到一个假设只有212个字节长的结构这一事实是非常有问题的。
可能存在其他问题,但这些问题是我目前看到的重要问题。