Stack Exchange
Binary tree - Dereferencing pointers
I was just trying to write a simple binary search tree program where the user can insert nodes and view all the nodes in the tree in either inorder,preorder or postorder mode. My code is 

#include <stdio.h>
#include <stdlib.h>

struct treenode
{
int data;
struct treenode *lchild;
struct treenode *rchild;
}*root;

void insertnode(struct treenode *p,int d)
{
    if(p==NULL)
    {
         // means the tree is empty
         p=(struct treenode *)malloc(sizeof(struct treenode));
         p->data=d;
         p->lchild=NULL;
         p->rchild=NULL;
    }

    else
    {
         // start comparing the new data from root
         if( d<p->data )
             insertnode((&(p->lchild)),d);

        else
             insertnode((&(p->lchild)),d);
    }
}

void preorder(struct treenode *p)
{
    if(p==NULL)
    {
        printf("\nThe list is empty");
    }

    else
    {
        printf("%d",p->data);
        preorder(p->lchild);
        preorder(p->rchild);
    }
}

void postorder(struct treenode *p)
{
    if(p==NULL)
    {
        printf("\nThe list is empty");
    }

    else
    {
        preorder(p->lchild);
        preorder(p->rchild);
        printf("%d",p->data);
    }
}

void inorder(struct treeode *p)
{
    if(p==NULL)
    {
        printf("\nThe list is empty");
    }

    else
    {
        preorder(p->lchild);
        printf("%d",p->data);
        preorder(p->rchild);
    }
}

int main(void)
{
    root=NULL;
    int choice,data;

    while(1)
    {
         printf("\nPress 1 for inserting a node in BST fashion: ");
         printf("\nPress 2 for traversing the tree in preorder fashion :");
         printf("\nPress 3 for traversing the tree in postorder fashion :");
         printf("\nPress 4 for traversing the tree in inorder fashion :");
         printf("\nPress 5 to exit :");


         printf("\nEnter your choice: ");
         scanf("%d", &choice);

    switch(choice)
    {
        case 1: printf("\nEnter the data to be inserted:");
            scanf("%d",&data);
            insertnode(root,data);
            break;

        case 2: preorder(root);
            break;

        case 3: postorder(root);
            break;

        case 4: inorder(root);
            break;

        case 5: exit(0);
            break;

        default: printf("\nYou have enetred an invalid choice. Please try again");
    }
}

return 0;
}


There are bunch of error messages saying 

dereferencing pointer to incomplete type


What is the problem ? Also i am not very comfortable with double indirection pointers, so can someone please explain how i can pass and retrieve double indirection pointers ( if i need to pass them at all in the above program).

You have a bug in inorder and postorder methods.

seems a bit OT should be in http://codereview.stackexchange.com/ since there are multiple errors

The following are just compilation errors, so fix these and your program will compile.
Problem #1:
You define your struct as:
struct treenode
{
    /* Blah blah... */
} *root;  /* Mistake: should be root, not *root */

Instead, name it root, not *root.

Problem #2:
You're calling insertnode() wrong. Instead of this:
insertnode((&(p->lchild)),d);  /* Mistake: taking the address of the pointer */

You should call it like this:
insertnode(p->lchild,d);


Problem #3:
You're defining root in main() wrong:
root = NULL;  /* Mistake: root is implicitly declared as int */

What you should do instead is:
struct treenode* root = NULL;


Problem #4:
You have a typo in the declaration of inorder():
void inorder(struct treeode *p)  /* Typo: should be treenode and not treeode */

It should be:
void inorder(struct treenode *p)


The next set of problems is logical errors in the program:
Problem #5:
in insertnode() you're always inserting a new value d into the left node. You should change either one of the recursive insertnode(p->lchild, d); calls to:
insertnode(p->rchild, d);

Depending on how you want to organize your tree.

Problem #6:
Just like AndersK pointed out, the passed pointer root never changes after it is passed to insertnode(), so that's a major bug.
In your case double indirection pointers are necessary when you want to change the passed pointer itself (i.e. point it to another address), and not change the pointee itself.
You want to change root inside insertnode(), so add another level of indirection and pass the address of root, i.e. &root, so that root can also be changed within the function.
Correspondingly, the declaration of insertnode() should be:
insertnode(struct treenode** p, int d)


Add more: Problem 5: insertion in left child used independently of the d value. :)

In order for you to change the data that a pointer is pointing to you need to supply one more level of indirection
e.g. you write
insertnode(root,data);

but root is set to NULL at start and cannot be changed inside insertnode the way you supply it to the function.
instead declare insertnode as
insertnode(struct treenode **p,int d)

and call insertnode with
insertnode(&root, data);

