我对书中的问题13.9提出了一个问题,即"破解编码面试".问题是编写一个支持分配内存的对齐alloc和free函数,在答案中代码如下:
void *aligned_malloc(size_t required_bytes, size_t alignment) {
void *p1;
void **p2;
int offset=alignment-1+sizeof?void*);
if((p1=(void*)malloc(required_bytes+offset))==NULL)
return NULL;
p2=(void**)(((size_t)(p1)+offset)&~(alignment-1)); //line 5
p2[-1]=p1; //line 6
return p2;
}
Run Code Online (Sandbox Code Playgroud)
我对第5行和第6行很困惑.为什么你必须做一个"和"因为你已经为p1添加了偏移?[-1]是什么意思?我在这里先向您的帮助表示感谢.
Uri*_*Uri 12
您的示例代码不完整.它什么都不分配.很明显你缺少一个设置p1指针的malloc语句.我没有这本书,但我认为完整的代码应该遵循这些方针:
void *aligned_malloc(size_t required_bytes, size_t alignment) {
void *p1;
void **p2;
int offset=alignment-1+sizeof?void*);
p1 = malloc(required_bytes + offset); // the line you are missing
p2=(void**)(((size_t)(p1)+offset)&~(alignment-1)); //line 5
p2[-1]=p1; //line 6
return p2;
}
Run Code Online (Sandbox Code Playgroud)
那么......代码做了什么?
我要猜测aligned_free是这样的:
void aligned_free( void* p ) {
void* p1 = ((void**)p)[-1]; // get the pointer to the buffer we allocated
free( p1 );
}
Run Code Online (Sandbox Code Playgroud)
Who*_*aig 11
p1是实际分配.p2是返回的指针,它引用超出分配点的内存,并为第一个位置的allignment和存储实际分配的指针留下足够的空间.当调用aligned_free()时,将检索p1以执行"real"free().
关于位数学,这会变得有点麻烦,但它有效.
p2=(void**)(((size_t)(p1)+offset)&~(alignment-1)); //line 5
Run Code Online (Sandbox Code Playgroud)
请记住,p1是实际的分配参考.对于踢,让我们假设以下,32位指针:
alignment = 64 bytes, 0x40
offset = 0x40-1+4 = 0x43
p1 = 0x20000110, a value returned from the stock malloc()
Run Code Online (Sandbox Code Playgroud)
重要的是原始版本malloc()在原始请求之上和之外分配额外的0x43字节空间.这是为了确保对齐数学和 32位指针的空间都可以考虑:
p2=(void**)(((size_t)(p1)+offset)&~(alignment-1)); //line 5
p2 = (0x20000110 + 0x43) &~ (0x0000003F)
p2 = 0x20000153 &~ 0x0000003F
p2 = 0x20000153 & 0xFFFFFFC0
p2 = 0x20000140
Run Code Online (Sandbox Code Playgroud)
p2在0x40边界上对齐(即0x3F中的所有位都为0)并留下足够的空间来存储原始分配的4字节指针,由p1引用.
自从我做对齐数学以来,它一直是永恒的,所以如果我找到这些位,请有人纠正这一点.