Como eu poderia definir o fundo de 3 bytes de um 4 bytes de comprimento, deixando o top byte intacta?
-
05-07-2019 - |
Pergunta
código relevante é o seguinte:
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[];
};
E apenas como um exemplo, a macro "get" é o seguinte:
//Get the size of the data contained within the chunk.
#define GET_CHUNK_SIZE(chunk) ((chunk.head) & 0xFFFFFF)
O byte superior Eu estou usando os bits para flags -. "Inuse" e "pode ??ser fundiram", e quaisquer outros adicionais que eu acho será útil
Agora que estou acabado, fornecendo informações básicas, como eu disse no título, eu preciso ser capaz de mudar os menores 3 bytes para o tamanho do pedaço é. Meu instinto inicial era bit a bit E o cabeçalho com o tamanho, uma vez que seria devidamente alinhados, mas depois percebi que poderia substituir a bandeira bytes também, porque ele automaticamente prefixado zeros até seu tamanho correspondeu ao longo. Não estou mesmo certo você pode bit a bit e um int e um longo. De qualquer forma, ajuda muito apreciada.
Solução
Como sobre: ??
head = (head & 0xff000000) | (new_size & 0x00ffffff)
Outras dicas
Por alguma razão a maioria das respostas recebidas até agora insistem em varrendo o potencial problema do tamanho de estouro para debaixo do tapete, ou seja, "e" o tamanho da parte com 0x00FFFFFF
assim tranquilamente descartando os bits de dimensão excessiva (se houver) e, em seguida, proceder para escrever a parte da cauda completamente sem sentido do tamanho para o campo. Eu não sei por que alguém iria fazer algo assim.
O código mais razoável pode parecer da seguinte maneira
assert((size & 0xFF000000) == 0);
chunk.head = (chunk.head & 0xFF000000) | size;
Não há razão válida para "e" o tamanho com 0x00FFFFFF
. Você deverá abortar ou pelo menos assert do tamanho excessivo, não silenciosamente descartar o excesso.
Use mordeu campos para fazer isso. Ele evita ter que usar as macros, agradável no depurador demasiado:
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))
É isso o que significava ou que eu perdi alguma coisa?