Home > Software engineering >  How do I make the following C structure more memory efficient?
How do I make the following C structure more memory efficient?

Time:09-02

I am trying to solve a rather challenging programming task. We are given the following 64-bit structure, which allows us to store a point in time accurate to the minute:

typedef struct
{
  unsigned char day;  //1 Byte
  unsigned char month; //1 Byte
  unsigned int year;  //4 Bytes
  unsigned char hours; //1 Byte
  unsigned char minutes; //1 Byte
} Time; //4 Bytes are probably used for padding

This structure has the size of 12 Bytes (I checked this and the struct really does use so much space). The task is to reduce the size to 8 Bytes and we are not allowed to use unions. We are supposed to use a lot of these structures, hence why we want to reduce the memory size.

The only thing I can think of is to change the unsigned int to unsigned short, but how can we get rid of the other two Bytes?

Kind regards

CodePudding user response:

The main problem here is that char have no alignment requirement, but int has a requirement of 4 byte alignment (on a 32 bit system). Meaning it must start at an address divisible by 4. Structs are guaranteed to start at an aligned address, so what you get is likely this:

unsigned char day;  //1 Byte
unsigned char month; //1 Byte
// 2 byte padding!
unsigned int year;  //4 Bytes
unsigned char hours; //1 Byte
unsigned char minutes; //1 Byte
// 2 byte padding!

The first two padding bytes are there to ensure that the int is aligned, the last two are there to ensure that the next struct in an array of structs start at an aligned address.

The fix is simple, just move year to the top of the struct:

unsigned int year;  //4 Bytes
unsigned char day;  //1 Byte
unsigned char month; //1 Byte
unsigned char hours; //1 Byte
unsigned char minutes; //1 Byte

And now the struct should be 8 bytes large with zero padding.

CodePudding user response:

Your current struct, since sizeof(Time) == 12 and sizeof(unsigned int) == 4 is layed out like this:

typedef struct
{
  unsigned char day;  //1 Byte
  unsigned char month; //1 Byte
// 2 bytes padding to align the `unsigned int`
  unsigned int year;  //4 Bytes
  unsigned char hours; //1 Byte
  unsigned char minutes; //1 Byte
// 2 bytes padding
} Time; 

You can reduce the size to 8 by moving year first. No padding needed here:

typedef struct
{
  unsigned int year;  //4 Bytes
  unsigned char day;  //1 Byte
  unsigned char month; //1 Byte
  unsigned char hours; //1 Byte
  unsigned char minutes; //1 Byte
} Time; 
  • Related