How might I set the bottom 3 bytes of a 4-byte long while leaving the top byte intact?
Relevant code is this:
typedef unsigned long int chunk_head;
typedef struct malloc_chunk
{
// Contains the size of the data in the chunk and the flag byte.
chunk_head head;
// Deliberately left unsized to allow overflow.
// Contains the payload of the chunk.
unsigned int data[];
};
And just as an example, the "get" macro is this:
//Get the size of the data contained within the chunk.
#define GET_CHUNK_SIZE(chunk) ((chunk.head) & 0xFFFFFF)
The upper byte I'm using the bits for flags -- "inuse" and "can be coalesced", and any additional ones that I find will be useful.
Now that I'm done providing background information, as I stated in the title, I need to be able to change the lower 3 bytes to how large the chunk is. My initial instinct was to bitwise AND the header with the size, since it would be properly aligned, but then I realized it might overwrite the f开发者_如何学Golag bytes too, because it automatically prepended zeroes until it size matched the long. I'm not even sure you can bitwise AND an int and a long. Anyway, help greatly appreciated.
How about:
head = (head & 0xff000000) | (new_size & 0x00ffffff)
For some reason most of the responses you received so far insist on sweeping the potential size overflow issue under the carpet, i.e. they "and" the chunk size with 0x00FFFFFF
thus quietly discarding the excessive size bits (if any) and then proceed to write the completely meaningless tail portion of the size into the field. I don't know why would anyone do something like that.
The more reasonable code might look as follows
assert((size & 0xFF000000) == 0);
chunk.head = (chunk.head & 0xFF000000) | size;
There is no valid reason to "and" the size with 0x00FFFFFF
. You should either abort or at least assert on excessive size, not quietly discard the excess.
Use bit fields to do this. It avoids having to use the macros, nice in the debugger too:
typedef struct chunk_head {
unsigned size:24;
unsigned inuse:1;
unsigned cancoalesce:1;
// Room for 6 more...
};
typedef struct malloc_chunk {
struct chunk_head head;
int data[];
};
chunk.head = (chunk.head & ~0xffffffL) | (new_lower_bits)
// retain the old top 8 bits
chunk.head &= 0xFF00000000
// set the lower 24 bits
chunk.head |= (0x00FFFFFF & new_bits)
#define SET_CHUNK_SIZE(chunk, size) (chunk.head = (chunk.head & 0xFF000000) | (size & 0x00FFFFFF))
Is that what you meant or did I miss something?
精彩评论