I need to store in memory a very long array.Each array item will be just a flag TRUE/FALSE (0/1). I need it to be very memory efficient so I have thought of implementing it as a masked-bit on top of an unsigned char region. Every char in memory should give me at least 8 flags. I have implemented the following functions:
static SIZE = 8; /* 8 bits = 1 byte = 1 char */
/* creates and initializes the array for N elements */
unsigned char *new_bit_array(long n) {
int extra = (n % SIZE) ? 1 : 0;
size_t ms = ((n / SIZE)+extra) * sizeof(unsigned char);
unsigned char *p = malloc(ms);
memset(p,0xFF,ms);
return p;
}
/* mask setter for nth bit of a char, call by function bit_array_set*/
char bit_mask_set(short nbit,short value) {
if (value)
return 0xFF;
if (nbit == 0)
return 0x7F;
else if (nbit == 1)
return 0xBF;
else if (nbit == 2)
return 0xDF;
else if (nbit == 3)
return 0xEF;
else if (nbit == 4)
return 0xF7;
else if (nbit == 5)
return 0xFB;
else if (nbit == 6)
return 0xFD;
else if (nbit == 7)
return 0xFE;
return 0xFF;
}
/* mask setter for nth element of the array */
void bit_array_set(unsigned char *p,long i,int value) {
p[i/] &= bit_mask_set(i % SIZE,value);
}
/* mask getter for nth bit of a char, call by function bit_array_get */
char bit_mask_get(short nbit) {
if (nbit == 0)
return 0x80;
else if (nbit == 1)
return 0x40;
else if (nbit == 2)
return 0x20;
else if (nbit == 3)
return 0x10;
else if (nbit == 4)
return 0x08;
else if (nbit == 5)
return 0x04;
else if (nbit == 6)
return 0x02;
else if (nbit == 7)
return 0x01;
return 0x00;
}
/* mask getter for nth element of the array */
short bit_array_get(unsigned char *p,long i) {
return p[i/SIZE] & bit_mask_get(i % SIZE) ? 1 : 0;
}
This code works fine but my question is if there are any built-in features in C or in any widely used library (i.e glib) that would provide the same functionality ?
... and also if there are any better ways of implementing bit_mask_get and bit_mask_set, the 7-branch IFs look ugly. Any other comments on this code are also very welcome.
switchstatement before and, to be honest, it doesn't change the code the a lot. It's basically the same thing.0xff ^ (1 << (7-nbit))should get rid of theif-elsestuff inbit_mask_set.