Comment définir les 3 derniers octets d'un 4 octets tout en laissant intact l'octet supérieur?

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

  •  05-07-2019
  •  | 
  •  

Question

Le code pertinent est le suivant:

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

Et juste à titre d’exemple, le "get" la macro est la suivante:

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

L'octet supérieur, j'utilise les bits pour les indicateurs - "inuse". et "peuvent être fusionnés", et tous les autres que je trouverai seront utiles.

Maintenant que j'ai fini de fournir des informations de base, comme je l'ai indiqué dans le titre, je dois pouvoir modifier les 3 octets inférieurs en fonction de la taille du morceau. Mon instinct initial était de lire bitwise ET l’en-tête avec la taille, puisqu’il serait correctement aligné, mais j’ai réalisé qu’il pourrait aussi écraser les octets de drapeau, car il préfixerait automatiquement les zéros jusqu’à ce que sa taille corresponde à long. Je ne suis même pas sûr que vous puissiez au niveau des bits ET un int et un long. En tout cas, l’aide est grandement appréciée.

Était-ce utile?

La solution

Que diriez-vous de:

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

Autres conseils

Pour une raison quelconque, la plupart des réponses que vous avez reçues insistent pour que le problème du trop-plein de taille potentielle soit balayé sous le tapis, c’est-à-dire qu'ils "et" la taille du bloc avec 0x00FFFFFF , éliminant ainsi discrètement les bits de taille excessive (le cas échéant), puis écrivant la portion de queue sans signification de la taille dans le champ. Je ne sais pas pourquoi quelqu'un ferait quelque chose comme ça.

Le code le plus raisonnable pourrait ressembler à ceci

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

Il n'y a pas de raison valable pour " et " la taille avec 0x00FFFFFF . Vous devez soit abandonner ou au moins affirmer votre excès de taille, ne pas jeter à la légère l'excès.

Utilisez des champs de bits pour cela. Cela évite d’avoir à utiliser les macros, bien dans le débogueur aussi:

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

Est-ce ce que vous vouliez dire ou ai-je oublié quelque chose?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top