I have an older project that reads a binary file into a struct using fread(). It uses Visual Studio 2017 (v141)
I upgraded the project to the newest C++ tools version (v142) for VS 2019, and also changed the solution from AnyCPU to x86.
I also changed Struct Member alignment from: 1 Byte (/Zp1) To: Default
because of this error:
Error C2338 Windows headers require the default packing option. Changing this can lead to memory corruption. This diagnostic can be disabled by building with WINDOWS_IGNORE_PACKING_MISMATCH defined.
But now the data is not being read correctly anymore.
This is the code I use to read the binary files:
FILE* RecipeFile;
short ReturnValue = 0; //AOK
if ((RecipeFile = fopen(rcpFile, "rb")) == NULL) {
ReturnValue = -1; //File open error
return(ReturnValue);
}
long sizeOfItem;
// obtain file size:
fseek(RecipeFile, 0, SEEK_END);
sizeOfItem = ftell(RecipeFile); // gives 771088
rewind(RecipeFile);
//sizeOfItem = sizeof(recipe); // gives 824304??
// now read the file contents:
int noOfItemsRead = fread(&recipe, sizeOfItem, 1, RecipeFile);
recipe
is a struct. See below.
I have noticed that sizeof(recipe)
gives a different result than the file size.
With toolset 141, I get 798276 bytes.
With toolset 142, I get 824304 bytes.
The actual file size is 771088 bytes.
Is the issue really caused by the change in struct member alignment?
How can I fix the error so the files are being read correctly again?
EDIT: I tried adding pragma pack directives to the struct like so:
#pragma pack(push, 1)
struct tRecipe {
RMPTableDescriptorType O2Flow;
RMPTableDescriptorType HeFlow;
RMPTableDescriptorType SiCl4Flow;
RMPTableDescriptorType GeCl4Flow;
RMPTableDescriptorType Extra_Flow;
RMPTableDescriptorType POCl3Flow;
RMPTableDescriptorType C2F6Flow;
RMPTableDescriptorType SiF4Flow;
RMPTableDescriptorType Cl2Flow;
RMPTableDescriptorType BCl3Flow;
RMPTableDescriptorType TTC_Temp;
RMPTableDescriptorType TTC_H2Flow;
RMPTableDescriptorType TTC_Ratio;
RMPTableDescriptorType LCC_Speed;
RMPTableDescriptorType LSC_Speed;
RMPTableDescriptorType LTC_Speed;
RMPTableDescriptorType TDS_Cursor;
RMPTableDescriptorType TDC_Ctrl;
RMPTableDescriptorType TPC_Ctrl;
RMPTableDescriptorType TSS_Cursor;
DLUTableDescriptorType DLU;
EXHTableDescriptorType EXH;
GENTableDescriptorType GEN;
PARTableDescriptorType PAR;
REFTableDescriptorType REF;
SETTableDescriptorType SET;
SUPTableDescriptorType SUP;
TDCTableDescriptorType TDC;
TDSTableDescriptorType TDS;
TSSTableDescriptorType TSS;
TTCTableDescriptorType TTC;
TPCTableDescriptorType TPC;
};
#pragma pack(pop)
typedef struct
{
RParam Value;
UInt16 Duration;
OptType Opt;
#if DOS
int Unused16BitVar; /* Established to allow Win32 NT Code to use 32bit */
#endif
}
RMPElementDescriptorType;
/*-----------------------------------------------------------------------------*/
typedef struct
{
UInt16 StartNoOf;
UInt16 EndNoOf;
Char8 StartRampType;
Char8 EndRampType;
RMPElementDescriptorType RMPElementArray[RAMP_ELEM_NO_OF];
}
RMPRampDescriptorType;
/*-----------------------------------------------------------------------------*/
typedef struct
{
UInt16 SizeInfo;
Char8 DBPTxtInfo[DBP_TXT_NO_OF];
RMPRampDescriptorType RMPRampArray[RAMP_NO_OF];
}
RMPTableDescriptorType;
but it does not seem to have any effect on the error.