【问题标题】:Trouble with binary tree structure implementation二叉树结构实现的问题
【发布时间】:2014-03-19 14:19:29
【问题描述】:

我正在尝试使用 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;
}

【问题讨论】:

    标签: c gdb segmentation-fault binary-tree c99


    【解决方案1】:

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

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

    第三个伙伴(当从左边分配失败时右边的那个)没有像其他两个伙伴一样初始化它的左右指针到NULL。这里有很多重复的代码,最好放在自己的函数中。

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

    【讨论】:

      猜你喜欢
      • 2011-11-28
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      • 2012-01-09
      • 2014-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多