1

相关代码是这样的:

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

举个例子,“get”宏是这样的:

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

我使用标志位的高位字节——“inuse”和“can be coalesced”,以及我发现的任何其他字节都是有用的。

现在我已经完成了提供背景信息,正如我在标题中所述,我需要能够将低 3 个字节更改为块的大小。我最初的直觉是按位 AND 标头与大小,因为它会正确对齐,但后来我意识到它也可能覆盖标志字节,因为它会自动添加零,直到它的大小与 long 匹配。我什至不确定您是否可以按位 AND 一个 int 和一个 long。无论如何,非常感谢帮助。

4

6 回答 6

7

怎么样:

head = (head & 0xff000000) | (new_size & 0x00ffffff)
于 2009-11-27T04:46:40.493 回答
5

出于某种原因,到目前为止,您收到的大多数回复都坚持将潜在的大小溢出问题扫在地毯下,即他们“和”块大小,0x00FFFFFF从而悄悄地丢弃过大的大小位(如果有的话),然后继续编写完整的无意义的尾部部分的大小变成了字段。我不知道为什么有人会做这样的事情。

更合理的代码可能如下所示

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

没有正当理由将大小与0x00FFFFFF. 您应该中止或至少断言过大的大小,而不是悄悄地丢弃多余的。

于 2009-11-27T05:02:41.477 回答
3

使用位域来做到这一点。它避免了必须使用宏,在调试器中也很好:

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[];
};
于 2009-11-27T05:29:05.853 回答
0

chunk.head = (chunk.head & ~0xffffffL) | (new_lower_bits)

于 2009-11-27T04:46:15.490 回答
0
#define SET_CHUNK_SIZE(chunk, size) (chunk.head = (chunk.head & 0xFF000000) | (size & 0x00FFFFFF))

这是你的意思还是我错过了什么?

于 2009-11-27T04:46:55.283 回答
0
// retain the old top 8 bits
chunk.head &= 0xFF00000000

// set the lower 24 bits
chunk.head |= (0x00FFFFFF & new_bits)
于 2009-11-27T04:50:36.773 回答