长时间潜伏,第一次海报.我是学生,两年没有接触过编程课程.现在我再次上课,我很难阅读和理解其他人的代码.我在这里有一个来自HMC的示例代码,其中包含C中简单内存分配器的一部分.
void free_block(ptr p) {
*p = *p & ~1; /* clear allocated flag */
next = (unsigned*)((char*)p + *p); /* find next blk */
if ((*next & 1) == 0) /* if not allocated... */
*p += *next; /* add to this block */
}
尽管有这些评论,我仍然对这里究竟发生了什么感到困惑.我知道代码的作用但我自己永远无法编写代码.如果有人可以解释这段代码的肮脏部分,我将非常感激.
最佳答案 由于字节对齐,分配大小不需要最后一个二进制位,
所以它被用作标志是否分配了该块.
分配的大小由块开头的值表示.
〜1是1的按位反转,意味着代替0x01,它是0xFE
*p = *p & ~1; /* clear allocated flag */
0xFFFFFFFE
(1111 1111 1111 1111 1111 1111 1111 1110)
使用当前值的按位AND运算清除最后一位.
结果是原始分配的大小.
从技术上讲,它取消引用p处地址的值,并使用0xFFFFFFFE执行按位AND运算,有效地保留所有值位,但最不重要
(确保价值不再以1结束,如果它最初的话).
next = (unsigned*)((char*)p + *p); /* find next blk */
‘next’是一个指向后续位置的指针
p [上述陈述中的结果值]
if ((*next & 1) == 0) /* if not allocated... */
*p += *next; /* add to this block */
如果’next’的二进制值不以一个结尾(按位AND运算),
取’p’处的值并在’next’处添加值,并将结果分配给’p’处的位置.
因此,换句话说,如果下一个块未分配,则原始块通过将该块大小添加到其自身(有效地移除它的存在)来包括它.
祝好运.我希望这有帮助.