7

I have a tree structure which I am adding a large amount of nodes too. The number of times this is done (tree cleaned between runs) and the number of nodes is given as a command line argument. For numbers of nodes roughly < 6000 and any number of runs the program performs as expected. However when the number of nodes exceeds this and the number of runs exceeds a low number around 50 the program causes a segmentation fault.

    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.

Using backtrace this tracks too

#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

Note that the addBody -> addBodyToCorrectQuad -> addBody recursion happens a large number of times at high number of nodes. The code with the malloc which fails is below.

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

The code I use to free the tree is as follows, with it being called on the root node and the internal flag being set to 0 when the tree is a leaf.

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

The tree struct looks like this

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

The code for adding Bodys to the tree is as follows with addBodyToCorrectQuad calling addBody on the quad that the body exists within.

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");
        }
    }
}
7
  • 1
    Sounds like you are modifying freed blocks somewhere. But it's hard to tell without having more code. Could you please add the code where you free your list? Commented Feb 11, 2013 at 20:47
  • Among the many things malloc() does to fulfill its memory requests, internal free-list(s) are often enumerated for best-fit matches, etc. I would highly suspect at least one of your prior allocations subsequently freed before this offending malloc() is overstepping its allocation bounds and toasting the free list. Put guards on both sides of your structure (a DWORD constant value like 0xBA53BA11 should suffice` and hard-panic if you ever encounter a block about to be freed with the guards overwritten. Commented Feb 11, 2013 at 20:48
  • 1
    Something is messing up your heap. Without the full program, it is impossible to know what/where (you are seeing the victim of an earlier scribbling over memory, there is no way to know when/where). Run your program under valgrind, and check its output carefully. Check that the program does track the life of each allocated area accurately. Check that it doesn't step over the limits of the areas (off-by-one errors in array indices, copying too long strings, ...). Commented Feb 11, 2013 at 20:54
  • I've added the code for both cleaning and adding bodies, hope this helps Commented Feb 11, 2013 at 21:32
  • Just for the humor of it, add *tree = NULL after each free(*tree); in cleanTree(), and add if(!tree || !*tree) exit(EXIT_FAILURE); to the beginning of the same function before all of that code. Trying to catch a bogus tree pointer here. Similar code in addBody() would probably be warranted as well. Finally remove the (Tree*) cast on your malloc() calls and check the compiler warnings carefully for "assumed return int messages" on those locations. In the process, verify you're including <stdlib.h> in your source files. Commented Feb 11, 2013 at 22:33

1 Answer 1

4

You have heap corruption somewhere -- someone is running off the end of an array or dereferencing an invalid pointer or using some object after it has been freed.

Try using valgrind or some other memory debugging tool to narrow down where the problem is.

Sign up to request clarification or add additional context in comments.

1 Comment

Succesfull run of valgrind on 1k bodys and 1k run ==3740== HEAP SUMMARY: ==3740== in use at exit: 23,088 bytes in 8 blocks ==3740== total heap usage: 4,028,036 allocs, 4,028,028 frees, 452,892,992 bytes allocated ==3740== ==3740== LEAK SUMMARY: ==3740== definitely lost: 0 bytes in 0 blocks ==3740== indirectly lost: 0 bytes in 0 blocks ==3740== possibly lost: 960 bytes in 3 blocks ==3740== still reachable: 22,128 bytes in 5 blocks ==3740== suppressed: 0 bytes in 0 blocks ==3740== Rerun with --leak-check=full to see details of leaked memory ==3740== 0 err supress 2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.