Here is my code :

#include <iostream.h>

int main (int argc, char * argv[])
{
    struct
    {   short   Signture;
        long    FileSize;
        short   Reserved1;
        short   Reserved2;
        long    ImgDataStartOff;
        long    InfoHeaderSize;
        long    Width;
        long    Height;
        short   Planes;
        short   NumbOfPix;
        long    Compression;
        long    SizeOfImgData;
        long    HRes;
        long    VRes;
        long    NumOfCol;
        long    NumOfImpCol;
        } Header;

    cout<<"Size of Header = "<<sizeof(Header)<<endl;

    system("PAUSE>nul");
    return EXIT_SUCCESS;}

I'm using Dev-CPP compiler.
Output is 56, but it must be 54.

Any explanation and solutions?

Dani AI

Generated

Short answer: sizeof is telling the truth — your compiler padded the structure so its in-memory footprint is 56 bytes. pointed to the padding explanation and suggested packing; 's memory dump shows the 2-byte gap between the first short and the following long, which is exactly why the size grew.

Why it happens: most ABIs require that a 4-byte type be aligned on a 4-byte boundary. A short at offset 0 uses bytes 0–1, the compiler inserts 2 bytes of padding at 2–3 so the next long starts at offset 4, then subsequent fields follow. The whole struct size is usually rounded up to the largest member alignment (commonly 4), so you get trailing padding too — that guarantees arrays of the struct keep correct alignment.

Practical options:

  • Use a packed definition (compiler-specific) with fixed-width types and verify it. Example pattern:

    #pragma pack(push,1)
    struct BMPPacked {
        std::uint16_t sig;
        std::uint32_t size;
        /* remaining fields in file order, using std::uint*_t */
    };
    #pragma pack(pop)
    
    static_assert(sizeof(BMPPacked) == 54, "unexpected header size");

    Packing makes sizeof match the on-disk header, but it is non-portable and can cause misaligned accesses on some architectures.

  • Safer and portable: read the 54 bytes into a byte buffer and decode fields explicitly (use std::uint8_t/std::uint16_t/std::uint32_t and assemble values with shifts, remembering BMP is little-endian). This avoids compiler packing quirks and endianness surprises.

If you are on Windows, the predefined BITMAPFILEHEADER / BITMAPINFOHEADER are the usual solution (as discovered). In all cases prefer fixed-width types and a runtime check (static_assert or a debug-size check) so your code behaves consistently across compilers.

Recommended Answers

All 8 Replies

I found this:


http://www.eskimo.com/~scs/C-faq/q2.13.html

and this:

9.10: Why does sizeof report a larger size than I expect for a structure type, as if there was padding at the end?

Structures may have this padding (as well as internal padding; see also question 9.5), so that alignment properties will be preserved when an array of contiguous structures is allocated.

So, is that the fault of sizeof() or the structure really holds 56 bytes?

I am gonna use this structure to gether the header of a bitmap file. My question is, am I gonna get 54 bytes or 56 bytes by a file stream function such as .read() ?

So, is that the fault of sizeof() or the structure really holds 56 bytes?

I am gonna use this structure to gether the header of a bitmap file. My question is, am I gonna get 54 bytes or 56 bytes by a file stream function such as .read() ?

What sizeof tells you is the truth.

Look into your compiler's documentation for a way to pack structures.

Look into your compiler's documentation for a way to pack structures.

What do you mean by packing structures?

Are there any gaps between variables in a structure? If so, how can we avoid them?

What do you mean by packing structures?

Are there any gaps between variables in a structure? If so, how can we avoid them?

I take it you didn't follow the link that already answered this question, nor did you take my advice about checking your compiler's documentation. Why ask for help and ignore the replies?

Thanx Dave, you are very kind...

I made some test on my code. Here is a sample :

#include <iostream.h>
#include <memory.h>

int main (int argc, char * argv[])
{
    struct
    {
        short   Signture;
        long    FileSize;
        short   Reserved1;
        short   Reserved2;
        long    ImgDataStartOff;
        long    InfoHeaderSize;
        long    Width;
        long    Height;
        short   Planes;
        short   NumOfPix;
        long    Compression;
        long    SizeOfImgData;
        long    HRes;
        long    VRes;
        long    NumOfCol;
        long    NumOfImpCol;
    }           Header;

    memset(&Header, 196, 75); //Fill the structure with '-' characters

    Header.Signture         =0x4241;
    Header.FileSize         =0x46454443;
    Header.Reserved1        =0x4847;
    Header.Reserved2        =0x4A49;
    Header.ImgDataStartOff  =0x4E4D4C4B;
    Header.InfoHeaderSize   =0x5251504F;
    Header.Width            =0x56555453;
    Header.Height           =0x5A595857;
    Header.Planes           =0x5C5B;
    Header.NumOfPix         =0x5E5D;
    Header.Compression      =0x6261605F;
    Header.SizeOfImgData    =0x66656463;
    Header.HRes             =0x6A696867;
    Header.VRes             =0x6E6D6C6B;
    Header.NumOfCol         =0x7271706F;
    Header.NumOfImpCol      =0x76757473;

    union
    {
        char  * CPtr;
        short * SPtr;
    }   Ptr;

    Ptr.SPtr = &Header.Signture;

    cout<<"Size of Header = "<<sizeof(Header)<<endl;

    for(int i=0; i<60; i++) cout<<i<<"\t"<<Ptr.CPtr[i]<<endl;

    system("PAUSE>nul");
    return EXIT_SUCCESS;
}

The output is :

Size of Header = 56
0       A
1       B
2       ─
3       ─
4       C
5       D
6       E
7       F
8       G
9       H
10      I
11      J
12      K
13      L
14      M
15      N
16      O
17      P
18      Q
19      R
20      S
21      T
22      U
23      V
24      W
25      X
26      Y
27      Z
28      [
29      \
30      ]
31      ^
32      _
33      `
34      a
35      b
36      c
37      d
38      e
39      f
40      g
41      h
42      i
43      j
44      k
45      l
46      m
47      n
48      o
49      p
50      q
51      r
52      s
53      t
54      u
55      v
56      ─
57      ─
58      ─
59      ─

As it is seen, the gap is between the variables "Signture" and "FileSize". There is a 2 byte gap.

But I managed to solve my problem. I used pre-defined windows structures which I found on MSDN.

I attached a doc file; have a look at it.

As mentioned in the links, there are ways to "pack" structures. There is no standard way, however, so each system may do it differently. One way might be #pragma pack. Then again it might not. Only your compiler's documentation will tell you (and you might want to mention which compiler you are using for the rest of us that can't see your computer).

[And I won't open attached .doc files.]

that is correct frnd. u just try one more long double or double variable it will show even higher value. its bcoz struct wil allocate memory arrays in terms of the longest variable(member) (may be a double,long,etc.,.)of the struct.In your problem it will allocate arrays of contigous memory in terms of size of long.
if u hv any doubt just add one more short varible it will remain same and u add even more one the size wil increas by 4. just try........ these all r bcoz of ur os.
ans:
11*4=44
10 more required for int. but in terms of long type it will allocate memory>=10 that is 3*4=12 which is >=10.
tot=44+12=56

commented: Don't bump old threads -1
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.