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;
};

ツリーにボディを追加するためのコードは、ボディが存在するクワッドをaddBodyToCorrectQuad呼び出すと次のようになります。addBody

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 に答える