Problem with char type in structures (MSVC)

H

h79

Hi everyone.

I've got a little problem...
I'll try illustrate it on example.

////////////
typedef unsigned long DWORD;
typedef unsigned char BYTE;

struct TST
{
BYTE a, b, c;
DWORD d;
};

int main()
{
ifstream *h_in;
TST s_tst;

h_in = new ifstream("tst.bin", ios::in | ios::binary |
ios::nocreate);
h_in->read((char*)&s_tst, sizeof(TST));
// 004010F0 6A 08 push 8 ; <- why 8, not 7 ?
// 004010F2 8D 45 E8 lea eax,[ebp-18h]
// 004010F5 50 push eax
// 004010F6 8B 4D F0 mov ecx,dword ptr [ebp-10h]
// 004010F9 E8 32 0A 00 00 call istream::read
(00401b30)

cout << hex << (int)s_tst.a << endl;
// printed: '1' <- OK
cout << hex << (int)s_tst.b << endl;
// printed: '2' <- OK
cout << hex << (int)s_tst.c << endl;
// printed: '3' <- OK
cout << hex << s_tst.d << endl;
// printed: 'cc000000' <- ERROR: should be '4'

delete h_in;
return 0;

}

//////////////

Below is the body of file 'tst.bin':

00000000|01 02 03 04-00 00 00

It's length is equal to 7.

Questions are:
1) Why offset of 'd' member i structure 'TST' is equal to 4, not 3?
2) What add in source code or change in project settings to fix it
(i.e. offset of 'd' member be equal 3)?

I want add that this problem apear in MSVC++, but doesn't apear in
Borland C++ compiler where builded program work fine.

Thanks
Harnas
 
D

David Hilsee

h79 said:
Hi everyone.

I've got a little problem...
I'll try illustrate it on example.

////////////
typedef unsigned long DWORD;
typedef unsigned char BYTE;

struct TST
{
BYTE a, b, c;
DWORD d;
};

int main()
{
ifstream *h_in;
TST s_tst;

h_in = new ifstream("tst.bin", ios::in | ios::binary |
ios::nocreate);
h_in->read((char*)&s_tst, sizeof(TST));
// 004010F0 6A 08 push 8 ; <- why 8, not 7 ?
// 004010F2 8D 45 E8 lea eax,[ebp-18h]
// 004010F5 50 push eax
// 004010F6 8B 4D F0 mov ecx,dword ptr [ebp-10h]
// 004010F9 E8 32 0A 00 00 call istream::read
(00401b30)

cout << hex << (int)s_tst.a << endl;
// printed: '1' <- OK
cout << hex << (int)s_tst.b << endl;
// printed: '2' <- OK
cout << hex << (int)s_tst.c << endl;
// printed: '3' <- OK
cout << hex << s_tst.d << endl;
// printed: 'cc000000' <- ERROR: should be '4'

delete h_in;
return 0;

}

//////////////

Below is the body of file 'tst.bin':

00000000|01 02 03 04-00 00 00

It's length is equal to 7.

Questions are:
1) Why offset of 'd' member i structure 'TST' is equal to 4, not 3?
2) What add in source code or change in project settings to fix it
(i.e. offset of 'd' member be equal 3)?

I want add that this problem apear in MSVC++, but doesn't apear in
Borland C++ compiler where builded program work fine.

The compiler may insert padding in structs to align the members properly.
If you want to change the compiler's behavior, consult its documentation or
a more appropriate newsgroup that discusses your compiler. I wouldn't
bother to change the compiler's settings, because changing the code would be
an easy solution that wouldn't require revisiting this problem later on
other compilers.

h_in->read((char*)&s_tst, sizeof(TST));

// Read each member instead
h_in->read((char*)&s_tst.a, sizeof(BYTE));
h_in->read((char*)&s_tst.b, sizeof(BYTE));
h_in->read((char*)&s_tst.c, sizeof(BYTE));
h_in->read((char*)&s_tst.d, sizeof(DWORD));
 
H

h79

Thanks.

Today I found also another solution about this problem (I think so).
It depends on use '#pragma pack' option. I used '#pragma pack(1)'.
After using this option all members in structures should be stored on
1-byte boundaries. For me it works fine.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top