structure

i have a problem with structure size.this is my structure :
1
2
3
4
5
6
7
8
struct bmpFileHeader{
char bm[2];
 long int fileSize;
 short int reserved1;
 short int reserved2;
 long int pixelOffset;
};
struct bmpFileHeader bmfh;

i used sizeof() to retrieve the size of each fundamental type:
short int = 2 Byte
long int = 4 byte
char bm[2]=2 Byte
but when i use sizeof(bmfh) , it returns 16 !!!!
(as you can see the sum of all data types are 14)
???????
But the bm char is an array of 2 so it would hold 6 slots...

EDIT: To clarify when you used sizeof(bm[2])) you were asking what the size of the address at the '2' in that array.
Last edited on
The compiler is just padding the structure to the nearest word boundary. It might decide to place members beginning at even byte-offsets, etc. for efficiency.

If you want to know what it's doing, clear all bits in its memory with memset, set all of the bits in each member, and then dump out the structure in binary or hex... Note that this should not be relied upon, it's compiler dependent.
Last edited on
Wow, it might help if I acctually did the math :p Oh well feel free to ignore my rambling
The compiler is just padding the structure to the nearest word boundary

so what should i do to read 14 byte of file using this structure?
this is what i did?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct bmpFileHeader{
char bm[2];
 long int fileSize;
 short int reserved1;
 short int reserved2;
 long int pixelOffset;
};


int main(){
struct bmpFileHeader bmfh;
cout<<sizeof(bmfh)<<endl;
ifstream myfile;
myfile.open("abc1.bmp",ios::out | ios::binary);
if (! myfile.is_open())
{cout<<"can not open input file!!!"<<endl;}
//myfile.seekg(2,ios::beg);
myfile.read((char *)&bmfh,sizeof(bmfh));
myfile.close();
cout<<"file Type : "<<bmfh.bm[0]<<bmfh.bm[1]<<"\tsize is : "<<2*sizeof(char)<<endl;
cout<<"size of the file : "<<bmfh.fileSize<<"\tsize is : "<<sizeof(bmfh.fileSize)<<endl;
cout<<"Reserved1 : "<<bmfh.reserved1<<"\tsize is: "<<sizeof(bmfh.reserved1)<<endl;
cout<<"Reserved2 : "<<bmfh.reserved2<<"\tsize is: "<<sizeof(bmfh.reserved2)<<endl;
cout<<"pixel offset : "<<bmfh.pixelOffset<<"\tsize is: "<<sizeof(bmfh.pixelOffset)<<endl;
cout<<"total size of BMP FILE HEADER : "<<sizeof(bmfh)<<endl;
system("pause");
return 0;
}// end of main 


i want to read 14 byte from a .bmp file.
This is a pretty whacky way to go about doing this. Do you know the order of the data that you are reading in the header already? If that's the case then you want to display the variable that you are assigning the data to not the size of the variable.

Give this a look over: http://www.cppreference.com/wiki/keywords/sizeof
wowwwwwwww
got the answer.
we can use #pragma like this:
1
2
3
4
5
6
7
8
9
#pragma pack(push,1)
struct bmpFileHeader{
char bm[2];
 long int fileSize;
 short int reserved1;
 short int reserved2;
 long int pixelOffset;
}bmfh;
#pragma pack(pop) 

This will change the byte alignment to 1 Byte. and thus size
of structure will be exactly 14 bytes.
thx guys for your help.
Last edited on
It looks like you have an alignment problem. The 2 bytes allocated for your array do not end on a 4 byte word boundary. So if your architecture uses 4 byte words the compiler may have added 2 bytes worth of padding after your array and before your four byte integer. That makes sure the 4 byte integer begins on a 4 byte word boundary.

You can possible instruct the compiler to pack more densely #pragma pack(2). But that is very non-portable. Also it won't solve any endian problems you may get reading binary integers in directly from a file like that.

I would be tempted to read in each field individually and make sure you have the right endianness when writing to the struct.

Here is some general info:

http://en.wikipedia.org/wiki/Data_structure_alignment
Here is some general info:

http://en.wikipedia.org/wiki/Data_structure_alignment


thx Galik for this usefull link.this is exactly what i am looking for and it clearly explains what happen in data structure padding.
thx again.
For a more complicated but more object oriented solution see these links. I have seen the pragma pack method used and it will work for many situations but it can also be confusing and error prone. There are also situations where you get a lot of confusing and weird compiler errors if you ever need to take the address of packed structure members (depending on the compiler).
http://www.parashift.com/c++-faq-lite/serialization.html
Topic archived. No new replies allowed.