Как я могу установить нижние 3 байта длиной 4 байта, оставив верхний байт нетронутым?

StackOverflow https://stackoverflow.com/questions/1806764

  •  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))

Это то, что ты имел в виду или я что-то упустил?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top