《Cracking the Coding Interview》——第13章:C和C++——题目9

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 }

 

你可能感兴趣的:(interview)