Sebastian Fahr said:
Hey there
I have a problem with my own Objects. I have to write a programm in school
that read objects from a binary file.
This Object has the following structure:
#pragma once
class Sandbox
{
int test1; // 4 Byte
int test2; // 4 Byte
int test3; // 4 Byte
int test4; // 4 Byte
int test5; // 4 Byte
int test6; // 4 Byte
char name[25]; //25 Bytes
// 4 + 4 + 4 + 4 + 4 + 4 + 25 Bytes = 49 Bytes
public:
Sandbox(void);
~Sandbox(void);
};
There are no virtual methods ore anything like that. It's like i posted
above. My problem is, i expected sizeof(Sandbox) = 49, but it is 52 when I
do sizeof(Sandbox). There are 3 Bytes too much.
Any ideas where these 3 Bytes are and how I can remove them?
Sebastian
P.S. Sorry for my bad english, it's not my native language.
As other people are stating, it's from alignment issues. It appears your
compiler/os is 4 byte aligned for integers. Intergers need to start on a 4
byte boundary. Consider if you had the class:
class Foo
{
int MyInt;
char MyChar;
};
MyInt would be aligned to a 4 byte boundary, such as 4000 (hypothetical).
MyChar would then take up the next byte. So 4000 - 4003 would be MyInt,
MyChar would be in 4004. Now what if you had an array of 2 of these? Foo
Data[2]; Data[1] without padding would start on 4005. But 4005 is not 4
byte aligned. So the compiler adds padding bytes, unused bytes, at the end
of the array so in effect it becomes:
class Foo
{
int MyInt;
char MyChar;
char unused[3];
};
so now Data[1] would start on a 4 byte boundary. And that's what you're
seeing with sizeof.
There are a few ways to deal with this. The common way is serialization.
Read each data into each variable.
pseudo code since I don't use fread and dont' even know the syntax:
fread( myfile, MyInstance.test1, sizeof( MyInstance.test1 ) );
fread( myfile, MyInstance.test1, sizeof( MyInstance.test2 ) );
etc...
Read each part of the structure/class individually.
Another method that is sometimes used (but not encouraged) is to write and
read the same structure. So you'd write a Foo (with thepadding) and read it
back in but since the written structure had the padding so will the read and
it'll line up. This can work sometimes, but when you're getting a file from
an external source (such as you are) you can't really do that.
Yet another method is to kludge. Find out where the padding is, see if it
effects you and if it doesn't, read all but hte padding. Ugly, prone to
errors and crashes and a kludge, not a fix.
fread( myfile, MyInstance, sizeof( MyInstance ) - 3 );
or manually put the nubmer of bytes
fread( myfile, MyInstance, 49 );
This is ugly, and although you may be attempted to use it, your teacher
probably wouldn't accept it anwyay. What happens when you add another char
to the data? You're going to have to search your code for the "magic
numbers" 3 or 49 and figure out what they should be.
on't do it.
Yet another way is some compilers have a #pragma or a command line switch to
turn packing off. Suce as one compiler uses:
#pragma pack(0)
saying don't use packing bytes. Although this can work, it is platform/OS
dependant and won't work on other platforms. Also, it can slow down some
computers as it has to fiddle intergers around in the CPU to line them up
right. Some CPUs will jsut plain crash when they try to use an unaligned
int.
So, what are your optoins? Well, I think I've listed them all, but the one I
would suggest is serialization.