C 二叉树结构实现的问题

C 二叉树结构实现的问题,c,gdb,segmentation-fault,binary-tree,c99,C,Gdb,Segmentation Fault,Binary Tree,C99,我正在尝试使用C语言中的二叉树实现一个内存管理模拟(buddy)。系统工作原理概述如下: 第一次输入值时,代码工作正常,并给出所需的输出。问题在第二次输入值时出现。我使用递归函数遍历树,得到一个错误,结构存在,但结构的成员不存在 Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1 (LWP 1)] 0x00010b2c in allocate (node=0x401ba18a, reqSiz

我正在尝试使用C语言中的二叉树实现一个内存管理模拟(buddy)。系统工作原理概述如下:

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

 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;
}
静态int分配(结构块*节点,int请求大小){
//基本情况!
printf(“我们称之为allocate\n”);
//检查请求是否太小
如果(要求尺寸<最小尺寸){
printf(“请求太小!\n”);
返回-1;
}
//检查请求是否太大
如果(请求大小>内存){
printf(“请求太大!\n”);
返回-1;
}
//检查当前块是否已分配
如果(节点->标志==1){
printf(“此块已分配!\n”);
返回-1;
}
//保存返回值的var
int returnVal=0;
//如果请求的大小小于或等于节点的一半
如果(重新调整尺寸)/2){
printf(“请求的大小小于或等于节点的一半\n”);
//检查是否有左侧节点,如果没有,则制作一个并调用allocate
如果(节点->左==NULL){
printf(“没有左边的节点,所以我们正在创建一个节点并用它调用allocate\n”);
结构块buddy1={.init=1.};
buddy1=findSpace();
buddy1.init=1;
buddy1.size=((节点->大小)/2);
printf(“大小为%d\n”,(节点->大小)/2);
buddy1.flag=0;
buddy1.parent=节点;
buddy1.left=NULL;
buddy1.right=NULL;
结构块buddy2={.init=1.};
buddy2=findSpace();
buddy2.init=1;
buddy2.size=((节点->大小)/2);
printf(“大小为%d\n”,(节点->大小)/2);
buddy2.flag=0;
buddy2.parent=节点;
buddy1.left=NULL;
buddy1.right=NULL;
节点->左=&buddy1;
节点->右=&buddy2;
returnVal=分配(节点->左侧,reqSize);
返回值;
}
//否则,在左侧节点上调用allocate
printf(“有一个左节点,因此我们在其上调用allocate\n”);
returnVal=分配(节点->左侧,reqSize);
如果(returnVal==-1){
printf(“由于某种原因无法分配左侧节点,因此我们正在检查是否存在右侧节点\n”);
如果(节点->右侧==NULL){
printf(“它没有。我们正在制作一个并调用它!\n”);
结构块buddy={.init=1.};
buddy=findSpace();
buddy.init=1;
buddy.size=((节点->大小)/2);
printf(“大小为%d\n”,(节点->大小)/2);
buddy.flag=0;
buddy.parent=节点;
//节点->左=空;
节点->右侧=&buddy;
returnVal=分配(&buddy,reqSize);
}
printf(“是的,所以我们调用了allocate”\n”);
returnVal=分配(节点->右侧,reqSize);
//返回值;
}
返回值;
}
如果(节点->标志==1){
返回-1;
}
printf(“这是我们需要的节点!\n”);
节点->标志=1;
printPostOrder(&blockArr[位置]);
返回1;
}

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

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

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

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