2014-04-25 20:37
题目:请设计一个字节对齐的malloc函数,配套上对应的free函数。要求这个函数分配出的内存块儿的首地址是某个值n的整数倍,n是2的整次幂,比如128、1024之类的。
解法:默认的malloc分配的首地址是不确定的,所以我们需要多分配一些内存,才能保证其中至少有一个字节能满足上述的要求,作为首地址。多余的地址不会被使用,但也要一起释放。每n个字节里,肯定有一个字节的地址是n的整数倍。所以我们至多需要多多分配n个字节。找到那个字节,作为结果返回即可。malloc说完了,free还存在一个问题。怎么知道最初由malloc分配的真实首地址呢?答案是:malloc的时候就找个地方存起来。至于存哪儿,放在那个内存块儿的前面或者后面都行,对于普通的far指针,需要额外四个字节的空间。这样要free的时候就不会抓瞎了。
代码:
1 // 13.9 Implement a memory-aligned malloc(), which returns a block of memory, and the address of the first byte is a multiple of a power of 2. 2 #include <cstdio> 3 #include <cstdlib> 4 using namespace std; 5 6 void *aligned_malloc(int nbytes, int align) 7 { 8 // boundary check 9 if (nbytes < 1 || align < 1) { 10 return nullptr; 11 } 12 13 // make sure that align is a power of 2 14 while ((align & align - 1) != 0) { 15 align = (align & align - 1); 16 } 17 18 void *p1, *p2; 19 20 p1 = (void *)malloc(nbytes + align - 1 + sizeof(void *)); 21 if (p1 == nullptr) { 22 return nullptr; 23 } 24 p2 = (void *)(((size_t)p1 + align - 1 + sizeof(void *)) & (~(align - 1))); 25 ((void **)p2)[-1] = p1; 26 27 return p2; 28 } 29 30 void aligned_free(void *ptr) 31 { 32 if (ptr == nullptr) { 33 return; 34 } 35 free(((void **)ptr)[-1]); 36 } 37 38 int main() 39 { 40 void *p1 = aligned_malloc(100, 4096); 41 void *p2 = malloc(100); 42 43 printf("p1 = %p\n", p1); 44 printf("p2 = %p\n", p2); 45 aligned_free(p1); 46 free(p2); 47 48 return 0; 49 }