Ricardo
Ricardo

Reputation: 369

Fixed-width Struct c++

I've created a struct with the following code:

struct d_entry{
   bool _free;
   char name[10];
   bool _dir;
   time_t _cDate;
   unsigned short _cluster;
   char reserved[6];
   unsigned int _size;      
};

I need my struct to be of a fixed-size of 32 bytes. According to my computer the following types (outside the struct) have the following sizes.

sizeof(bool) = 1 byte
sizeof(char) = 1 byte   
sizeof(time_t) = 8 bytes   
sizeof(short) = 2 bytes  
sizeof(int) - 4 bytes

When I run the size of any d_entry, the size is 40 bytes. For some reason, the time_t and long types are being interpreted as 16 bytes. I haven't been able to get around this situation.

Upvotes: 1

Views: 419

Answers (2)

buratino
buratino

Reputation: 1518

As Borgleader pointed out, you are experiencing data structure padding.

As an alternative to #pragma pack(1), you can make use of the gcc keyword __attribute__ to specify that the structure should not have padding.

struct d_entry{
   bool _free;
   char name[10];
   bool _dir;
   time_t _cDate;
   unsigned short _cluster;
   char reserved[6];
   unsigned int _size;      
}__attribute__(( packed ));

In general, when packing a structure, you should be sure to access the structure's members only through . or -> (see this post).

Upvotes: 1

Borgleader
Borgleader

Reputation: 15916

You're running into padding and alignment issues. Different types have different requirements. You can use a compiler specific pragma to pack your members and overcome this issue:

#include <iostream>

struct foo{
   bool _free;
   char name[10];
   bool _dir;
   time_t _cDate;
   unsigned short _cluster;
   char reserved[6];
   unsigned int _size;      
};

#pragma pack(1)
struct bar{
   bool _free;
   char name[10];
   bool _dir;
   time_t _cDate;
   unsigned short _cluster;
   char reserved[6];
   unsigned int _size;      
};

int main()
{
    std::cout << sizeof(foo) << std::endl;
    std::cout << sizeof(bar) << std::endl;

    return 0;
}

This gives a size of 40 for foo (as you got), and 32 for bar (as you expected). See on Coliru

Upvotes: 4

Related Questions