7

我有一个树结构,我也添加了大量节点。完成的次数(在运行之间清理树)和节点数作为命令行参数给出。对于大约 < 6000 的节点数量和任意数量的运行,程序按预期执行。但是,当节点数超过此值并且运行次数超过 50 左右时,程序会导致分段错误。

    Program received signal SIGSEGV, Segmentation fault.
    _int_malloc (av=0x7ffff7201740 <main_arena>, bytes=112) at malloc.c:3570
    3570    malloc.c: No such file or directory.

也使用回溯跟踪

#0  _int_malloc (av=0x7ffff7201740 <main_arena>, bytes=112) at malloc.c:3570
#1  0x00007ffff6ecbfb5 in __GI___libc_malloc (bytes=112) at malloc.c:2924
#2  0x0000000000401a99 in createTreeForQuad (quad=...) at cs257.c:217
#3  0x0000000000401b3a in addQuadsToTree (tree=tree@entry=0x2f965c8) at cs257.c:230
#4  0x0000000000401dec in addBody (tree=tree@entry=0x2f965c8, body=...) at cs257.c:292
#5  0x0000000000402146 in addBodyToCorrectQuad (body=..., tree=tree@entry=0x2f961c8) at cs257.c:245
#6  0x0000000000401eaf in addBody (tree=tree@entry=0x2f961c8, body=...) at cs257.c:296
#7  0x0000000000402146 in addBodyToCorrectQuad (body=..., tree=tree@entry=0x2f95dc8) at cs257.c:245

请注意,addBody -> addBodyToCorrectQuad -> addBody 递归在大量节点处发生大量次数。malloc 失败的代码如下。

Tree *createTreeForQuad(Quad quad) {
Tree *tree;
tree = (Tree *)malloc(sizeof*tree);
if (tree != NULL){
    tree->quad = quad;
    tree->internal = 0;
    tree->bodyEmpty = 1;
    return tree;
}else{
   printf("\n ------------------------------------ MALLOC FAILED----------------------------------------");
    }
}

我用来释放树的代码如下,在根节点上调用它,当树是叶子时,内部标志设置为 0。

void cleanTree(Tree **tree) {
    if((*tree)->internal == 0) {
        free(*tree);
    }
    else{
        cleanTree(&((*tree)->NE));
        cleanTree(&((*tree)->SE));
        cleanTree(&((*tree)->SW));
        cleanTree(&((*tree)->NW));
        cleanTree(&((*tree)->NE1));
        cleanTree(&((*tree)->NW1));
        cleanTree(&((*tree)->SE1));
        cleanTree(&((*tree)->SW1));
        free(*tree);
    }
}

树结构看起来像这样

typedef struct Tree Tree;
struct Tree {
    Body body;
    Quad quad;
    Tree *NE;
    Tree *NW;
    Tree *SE;
    Tree *SW;
    Tree *NE1;
    Tree *NW1;
    Tree *SE1;
    Tree *SW1;
    int internal;
    int bodyEmpty;
};

将 Body 添加到树的代码如下,addBodyToCorrectQuad调用addBody了 body 所在的 quad。

void addBody(Tree **tree, Body body) {
   if( (*tree)->bodyEmpty == 1) { 
        (*tree)->body = body;
        (*tree)->bodyEmpty = 0;
    }
    else {
        if((*tree)->internal) {
            (*tree)->body = combineBody((*tree)->body, body);
            addBodyToCorrectQuad(body, tree);
            //printf("B\n");
        }
        else{
            (*tree)->internal = 1;   /
            addQuadsToTree(tree);
            //printf("%f",((*tree)->NW)->quad.x);
            addBodyToCorrectQuad((*tree)->body, tree);
            (*tree)->body = combineBody((*tree)->body, body);
            addBodyToCorrectQuad(body, tree);
            //printf("C\n");
        }
    }
}
4

1 回答 1

3

您在某处发生了堆损坏——有人在数组末尾运行或取消引用无效指针或在释放某个对象后使用它。

尝试使用valgrind或其他一些内存调试工具来缩小问题所在。

于 2013-02-11T20:59:19.613 回答