Stack Exchange
push operation on stack using linked list fails
I am trying to create a stack using single linked list, my push operation doesn't insert data into the linked list
This is what I have tried so far,
typedef struct element {
    int data;
    struct element *next;
}node;

The push method
void push(node *root, int data) {
    if(root == NULL) {
        root = (node *) malloc (sizeof(struct element));
        root->data = data;
        root->next = NULL;
    }
    else {
        node *temp = (node *) malloc (sizeof(struct element));
        temp->data = data;
        temp->next = root;
        root = temp;
    }
}

In my main method, I haven't malloced the head pointer, 
and this is how I call the push method, 
push(head, data);

How can I make the push operation work?

The root pointer is modified in the push function. This value is not propagated to main. One way to do it is to return the root pointer.
node* push(node *root, int data) {
  if(root == NULL) {
    root = (node *) malloc (sizeof(struct element));
    root->data = data;
    root->next = NULL;
  }
  else {
    node *temp = (node *) malloc (sizeof(struct element));
    temp->data = data;
    temp->next = root;
    root = temp;
  }
  return root;
}

And in main, you need to call it like, 
head = push(head, data);


Your root value is a pointer, but the address is passed by value, meaning that if you modify the address, it will have no side effect outside the scope of the function.
Use:
void push(node **root, int data )

To be able to modify the value of root 
and:
push( &head, data )


I believe this is the problematic line of code:
root = temp;

You are assigning a local node* called root to another local node* called temp, but this assignment is not "sticking" outside of the push() function.  To make it stick, you can dereference as follows:
*root = *temp;

Full code:
void push(node *root, int data) {
    if (root == NULL) {
        root = (node *) malloc (sizeof(struct element));
        root->data = data;
        root->next = NULL;
    }
    else {
        node *temp = (node *) malloc (sizeof(struct element));
        temp->data = data;
        temp->next = root;
        *root = *temp;
    }
}


Beware of duplicating code.
As others have responded, your function needs to return the pointer to the malloc()'d buffer...
And, we can use 'root' to our advantage, NULL or not...
node_t *push( node_t *root, int data ) {
    node_t *np = (node_t *) malloc( sizeof(node_t) );
    np->data = data;
    np->next = root;
    return np;
}

The "_t" suffix used above is a convention to help distinguish the name of a datatype from a variable name.
