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 }

 

 posted on 2014-04-25 20:47  zhuli19901106  阅读(250)  评论(0编辑  收藏  举报