Come posso impostare i 3 byte inferiori di una lunghezza di 4 byte lasciando intatto il byte superiore?

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

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

È stato utile?

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?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top