¿Cómo puedo configurar los 3 bytes inferiores de un byte de 4 bytes y dejar intacto el byte superior?

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

  •  05-07-2019
  •  | 
  •  

Pregunta

El código relevante es este:

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[];
};

Y solo a modo de ejemplo, el " obtener " macro es esta:

//Get the size of the data contained within the chunk.
#define GET_CHUNK_SIZE(chunk) ((chunk.head) & 0xFFFFFF)

El byte superior Estoy usando los bits para las marcas - " inuse " y " puede fusionarse " ;, y cualquier otro adicional que encuentre será útil.

Ahora que he terminado de proporcionar información de fondo, como lo indiqué en el título, necesito poder cambiar los 3 bytes inferiores al tamaño del fragmento. Mi instinto inicial fue a nivel de bit Y el encabezado con el tamaño, ya que se alinearía correctamente, pero luego me di cuenta de que también podría sobrescribir los bytes de la bandera, ya que automáticamente anexaba los ceros hasta que el tamaño coincidía con el largo. Ni siquiera estoy seguro de que puedas a nivel de bit Y un int y un largo. De todos modos, ayuda muy apreciada.

¿Fue útil?

Solución

Cómo sobre: ??

head = (head & 0xff000000) | (new_size & 0x00ffffff)

Otros consejos

Por alguna razón, la mayoría de las respuestas que recibió hasta ahora insisten en barrer el problema de desbordamiento de tamaño potencial debajo de la alfombra, es decir, " y " el tamaño del fragmento con 0x00FFFFFF descarta silenciosamente los bits de tamaño excesivo (si corresponde) y luego procede a escribir en el campo la parte de la cola completamente sin sentido del tamaño. No sé por qué alguien haría algo así.

El código más razonable podría verse como sigue

assert((size & 0xFF000000) == 0);
chunk.head = (chunk.head & 0xFF000000) | size;

No hay una razón válida para " y " el tamaño con 0x00FFFFFF . Debes abortar o al menos afirmar sobre un tamaño excesivo, no descartar silenciosamente el exceso.

Usa campos de bits para hacer esto. Evita tener que usar las macros, también en el depurador:

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

¿Eso es lo que quisiste decir o me perdí algo?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top