Come posso impostare i 3 byte inferiori di una lunghezza di 4 byte lasciando intatto il byte superiore?
-
05-07-2019 - |
Domanda
Il codice rilevante è questo:
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 solo come esempio, il " get " la macro è questa:
//Get the size of the data contained within the chunk.
#define GET_CHUNK_SIZE(chunk) ((chunk.head) & 0xFFFFFF)
Il byte superiore sto usando i bit per flag - & in; inuse " e "può essere coalizzato", e qualsiasi ulteriore che trovo sarà utile.
Ora che ho finito di fornire informazioni di base, come ho affermato nel titolo, devo essere in grado di cambiare i 3 byte inferiori con la dimensione del blocco. Il mio istinto iniziale era di bit a bit E l'intestazione con la dimensione, poiché sarebbe stata correttamente allineata, ma poi ho capito che potrebbe sovrascrivere anche i byte della bandiera, perché anteponeva automaticamente gli zero fino a quando le dimensioni corrispondevano al lungo. Non sono nemmeno sicuro che puoi bit per bit E un int e un lungo. Ad ogni modo, aiuto molto apprezzato.
Soluzione
Che ne dici di:
head = (head & 0xff000000) | (new_size & 0x00ffffff)
Altri suggerimenti
Per qualche motivo, la maggior parte delle risposte che hai ricevuto finora insiste per spazzare via il potenziale problema di overflow delle dimensioni sotto il tappeto, cioè "e"; la dimensione del blocco con 0x00FFFFFF
scartando silenziosamente i bit di dimensione eccessiva (se presenti) e quindi procedendo a scrivere nel campo la porzione di coda completamente insignificante della dimensione. Non so perché qualcuno dovrebbe fare qualcosa del genere.
Il codice più ragionevole potrebbe apparire come segue
assert((size & 0xFF000000) == 0);
chunk.head = (chunk.head & 0xFF000000) | size;
Non esiste un motivo valido per " e " la dimensione con 0x00FFFFFF
. Dovresti interrompere o affermare almeno di dimensioni eccessive, non scartare tranquillamente l'eccesso.
Usa i campi bit per fare questo. Evita di usare le macro, anche nel debugger:
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))
È quello che volevi dire o mi sono perso qualcosa?