Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

原文:
"
该结构主要是描述堆的基本信息,包括

堆对应的 arena 的地址
由于一个线程申请一个堆之后,可能会使用完,之后就必须得再次申请。因此,一个线程可能会有多个堆。prev 即记录了上一个 heap_info 的地址。这里可以看到每个堆的 heap_info 是通过单向链表进行链接的。
size 表示当前堆的大小
最后一部分确保对齐(这里负数使用的缘由是什么呢?)

"

这里负数使用的缘由是什么呢?
研究了好二十分钟才理解,主要是这个写法太骚脑了..先根据注释中that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
可以理解他想表达的是6个指针的空间, 再加占位符,目前没想到为什么对齐为16位,
但是我们可以直接分析他的式子-6 * SIZE_SZ & MALLOC_ALIGN_MASK
其实想表达的是占位数量为 16 * x - 6 * SIZE_SZ
其中x是任意自然数,这最终就可以导致16位对齐
注意,由于16 * x这个数在任意时候都是16的倍数,所以他在以16为模的运算中,必然是溢出的,且溢出后结果必然为0
所以结果就是0 - 6 * SIZE_SZ
注意上一行的推理的前提是以16为模,否则结果肯定和原来的方案不同,所以就变成了(- 6 * SIZE_SZ) % 16

或者这样写
pad
= (16 * x - 6 * SIZE_SZ) % 16 # 最后取模是为了把可能的负数结果取值为正数
= 16 * x % 16 - 6 * SIZE_SZ % 16 # 上一个式子里结果必然是正数,这个式子里可能会是模运算后的正数或者是模运算对应结果的负数(事实上一定是模运算得到正数结果之前的负数,比如%8的正数结果3,那么他的负数结果可以是-5,他们只是表达有所不同)
= (0 - 6 * SIZE_SZ )% 16 # 为了把上式的模运算负数结果变为正数结果,再取模一次就好了,反正同一个模运算多几次结果都是一样的。
= -6 * SIZE_SZ % 16
为了保证结果是自然数,负号的运算必须在求余之前

You must be logged in to vote

Replies: 1 comment · 1 reply

Comment options

@ClarkCh 分析得挺好的鸭~ 可以给 Wiki 提个 PR 么~

You must be logged in to vote
1 reply
@zhubblego
Comment options

int num = -5;
int num2 = -5 % 8; //-5
int num3 = -5 & 7; //3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.