2014-03-19 61 views
0

我想实现一个内存管理模拟(好友),采用二叉树C的系统是如何工作的想法是这里概述:麻烦与二叉树结构实现

http://en.wikipedia.org/wiki/Buddy_memory_allocation

第一次输入一个值时,代码工作正常,并给出所需的输出。第二次输入值时会出现问题。我使用递归函数来遍历树,并且我得到一个错误,从而结构存在,但是结构的成员不存在。

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 1 (LWP 1)] 
0x00010b2c in allocate (node=0x401ba18a, reqSize=1000) at temp.c:95 
95   if(node->flag == 1){ 
(gdb) print node 
$1 = (struct block *) 0x401ba18a 
(gdb) print node->flag 
Cannot access memory at address 0x401ba192 

相关的代码贴在下面,任何帮助将真正理解!

static int allocate(struct block* node, int reqSize) { 
//BASE CASES! 
printf("We've called allocate\n"); 
//check if the request is too small 
if(reqSize < minSize){ 
    printf("The request is too small!\n"); 
    return -1; 
} 
//check if the request is too large 
if(reqSize > memory){ 
    printf("The request is too large!\n"); 
    return -1; 
} 
//check if the current block is already allocated 
if(node->flag == 1){ 
    printf("This block has been allocated!\n"); 
    return -1; 
    } 
    //var to hold returned value 
    int returnVal = 0; 
    //If the size of the request is less than or equal to half the node 
    if(reqSize<(node->size)/2){ 
    printf("The size of the request is less than or equal too half the node\n"); 
    //check if there is a left node, if not, make one and call allocate 
    if(node->left == NULL){ 
     printf("There's no left node so we are making one and calling allocate with  it\n"); 

     struct block buddy1 = { .init =1.}; 
     buddy1 = findSpace(); 
     buddy1.init = 1; 
     buddy1.size = ((node->size)/2); 
     printf("with the size %d\n",(node->size)/2); 
     buddy1.flag = 0; 
     buddy1.parent = node; 
     buddy1.left = NULL; 
     buddy1.right = NULL; 

     struct block buddy2 = { .init =1.}; 
     buddy2 = findSpace(); 
     buddy2.init = 1; 
     buddy2.size = ((node->size)/2); 
     printf("with the size %d\n",(node->size)/2); 
     buddy2.flag = 0; 
     buddy2.parent = node; 
     buddy1.left = NULL; 
     buddy1.right = NULL; 

     node->left = &buddy1; 
     node->right = &buddy2; 
     returnVal = allocate(node->left,reqSize); 
     return returnVal; 
    } 
    //otherwise call allocate on the left node 
    printf("There is a left node so we are calling allocate on it\n"); 
    returnVal = allocate(node->left,reqSize); 

    if(returnVal == -1){ 
     printf("couldn't allocate a left node for some reason, so we are checking if a right node exists\n"); 
     if(node->right ==NULL){ 
      printf("it doesn't. We're making one and calling allocate on it!\n"); 
      struct block buddy = { .init =1.}; 
      buddy = findSpace(); 
      buddy.init = 1; 
      buddy.size = ((node->size)/2); 
      printf("with the size %d\n",(node->size)/2); 
      buddy.flag = 0; 
      buddy.parent = node; 
      //node->left = NULL; 
      node->right = &buddy; 
      returnVal = allocate(&buddy,reqSize); 
      } 
      printf("it did, so we are calling allocate on it\n"); 
      returnVal = allocate(node->right,reqSize); 
      //return returnVal; 

    } 
    return returnVal; 
} 

if(node->flag == 1){ 
    return -1; 
} 

printf("This is the node we need!\n"); 
node->flag = 1; 
printPostOrder(&blockArr[position]); 
return 1; 
} 

回答

1

你的好友节点是局部变量,分配在堆栈上,并在分配函数返回时被销毁。您不显示block结构或findSpace函数的定义,因此很难提供更多帮助。

为什么你部分初始化每个伙伴(.init被分配了一个浮点数1),然后立即覆盖整个结构的返回值findSpace

第三个好友(从左边分配的右边失败)没有像其他两个好友那样初始化左边和右边的指针NULL。这里有很多复制的代码可能更好地放在它自己的函数中。

通常情况下,树结构是隐含的,您只需在位于每个空闲块前面的结构中创建一个空闲列表。合并区块时,您可以通过将您的地址与您的大小进行异或来确定您的好友的地址。所有你需要的是每块一位,告诉你,如果该伙伴是免费的(并有一个头结构),如果是这样,你可以检查头,以确保它是相同的大小。所需的唯一额外存储空间是具有每个最小可分配块1位的位矢量,使您可以快速确定是否存在标题,而无需扫描空闲列表。哦,自由列表应该双重链接,允许您从中间删除元素(无需从头开始扫描列表)。如果您愿意为分配的块添加标题,则可用大小将不再是2的幂,但可以避免需要外部位向量。