2

I'm trying to code a C program that convert a binary tree into a linket list. Here's the declaration of these to structures :

struct treeNode {
    double data;
    struct treeNode* leftP;
    struct treeNode* rightP;
};

struct listNode{
    double data;
    struct listNode* nextP;
};

The algorithm works but I have waht I expect to be a memory error at the end of the program's execution (process returned 0xC0000005). After some search with this code, I guess it comes from a bad management of pointers but I can't find my mistake. Here's my main function :

int main()
{
    /*Creation of the binary tree*/
    struct treeNode tree[10];
    int i;
    for(i=0;i<10;i++)
        tree[i].data = (float)i;
    tree[0].leftP = &(tree[1]);
    tree[0].rightP = &(tree[2]);
    //....... (creation of the tree)
    tree[9].rightP = 0;

    //Conversion
    void** elem = malloc(sizeof(void**));
    *elem = (void*)(&tree);
    tree2list(elem);
    struct listNode* list = (struct listNode*)(*elem);
    printList(list);
    printf("end1");
    //free(elem);
    printf("end2\n");
    return 0;
}

The program reach end2 if I comment the free line and end1 if I try to free the variable elem. Here's the tree2list function :

void tree2list(void** node)
{
    struct treeNode* tree = (struct treeNode*)(*node); //tree to convert
    int size = treeSize(tree);
    struct listNode* list = malloc(size*sizeof(struct listNode*)); //Creation of a list with same number of nodes than in the tree
    *node = (void*) list;
    struct listNode* currentListNode = list;
    struct treeNode* currentTreeNode = tree;
    struct treeNode* nextNode;
    struct listNode* old = 0;
    struct treeNode* stack = 0; //Stack composed of treeNode linked by their leftP pointer
    while(currentTreeNode)
    {
        if(currentTreeNode->leftP) //if left branch exists, add the current node to the stack and explore this left branch
        {
            nextNode = currentTreeNode->leftP;
            stackPush(&stack, currentTreeNode);
            currentTreeNode = nextNode;
        }
        else //if left branch doesn't exist, add the currentNode to the list
        {
            currentListNode->data = currentTreeNode->data;
            currentListNode->nextP = 0;
            if(old)
                old->nextP = currentListNode;
            old = currentListNode++;
            if(currentTreeNode->rightP)
                currentTreeNode = currentTreeNode->rightP;
            else
                currentTreeNode = stackPop(&stack);
        }
    }
}

This function of other function like stackPush and stackPop that seem to work well. Do someone see the source of error code ?

Thanks

Hugo
  • 43
  • 1
  • 1
  • 4
  • 1
    [here](http://stackoverflow.com/questions/3411793/convert-a-binary-tree-to-linked-list-breadth-first-constant-storage-destructiv) – Yann Jun 12 '14 at 12:17
  • 3
    `struct listNode* list = malloc(size*sizeof(struct listNode*));` should be `struct listNode* list = malloc(size*sizeof(struct listNode));` – BLUEPIXY Jun 12 '14 at 12:19
  • 2
    I think you are using Visual studio, so use its integrated debugger to identify line of failure and also why it fails. – Rohan Jun 12 '14 at 12:20

1 Answers1

2
void** elem = malloc(sizeof(void**));

This doesn't make any sense. Think about what you are actually trying to do here. Similarly, this doesn't make any sense either:

struct listNode* list = malloc(size*sizeof(struct listNode*));

In the first malloc, you were probably supposed to allocate an array of pointers, and then point to them with a pointer-to-pointer. You allocated one single pointer-to-pointer. If that was the intention, why allocate it dynamically in the first place?

In the second malloc, you were probably supposed to allocate an array of structs. You allocated an array of pointer-to-struct.

And rather than allocating a pointer-to-pointer lookup table segmented all over the heap, consider properly allocating a 2D array.

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Thank for your answer. For the first problem, I changed the line by the following code which I think is more correct : `struct treeNode* treeToConvert = &(tree[0]); struct treeNode** pointerToTree = &treeToConvert; tree2list((void**)pointerToTree); struct listNode* list = (struct listNode*)(*pointerToTree);` Not it seems to run without problem. For the second problem I don't really understand my mistake. I create a number of pointers to listNode structures that will be sent as a result. – Hugo Jun 12 '14 at 13:51