Как я могу установить нижние 3 байта длиной 4 байта, оставив верхний байт нетронутым?
-
05-07-2019 - |
Вопрос
Соответствующий код такой:
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[];
};
И в качестве примера, " get " макрос это:
//Get the size of the data contained within the chunk.
#define GET_CHUNK_SIZE(chunk) ((chunk.head) & 0xFFFFFF)
Старший байт. Я использую биты для флагов - " inuse " и "могут быть объединены", и любые дополнительные, которые я нахожу, будут полезны.
Теперь, когда я закончил предоставлять справочную информацию, как я указал в заголовке, мне нужно иметь возможность изменить младшие 3 байта на размер блока. Мой первоначальный инстинкт был побитовый И заголовок с размером, так как он был бы правильно выровнен, но потом я понял, что он также может перезаписывать байты флага, потому что он автоматически добавляет нули до тех пор, пока его размер не будет соответствовать длинному. Я даже не уверен, что вы можете побитовый И int и long. В любом случае, помощь очень ценится.
Решение
Как насчет:
head = (head & 0xff000000) | (new_size & 0x00ffffff)
Другие советы
По некоторым причинам большинство ответов, которые вы получили до сих пор, настаивают на том, чтобы скрыть потенциальную проблему переполнения размера, то есть они " размер куска с 0x00FFFFFF
, таким образом, незаметно отбрасывает биты чрезмерного размера (если они есть), а затем приступает к записи совершенно бессмысленной хвостовой части размера в поле. Я не знаю, зачем кому-то делать что-то подобное.
Более разумный код может выглядеть следующим образом
assert((size & 0xFF000000) == 0);
chunk.head = (chunk.head & 0xFF000000) | size;
Нет веских причин для " и " размер с 0x00FFFFFF
. Вы должны либо прервать, либо хотя бы заявить о чрезмерном размере, но не отказываться от лишнего.
Используйте битовые поля для этого. Это избавляет от необходимости использовать макросы, что приятно в отладчике:
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 & amp; ~ 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))
Это то, что ты имел в виду или я что-то упустил?