Creating a linked list of n length
naked malloc calls

Note that malloc() simply allocates memory - you have no guarantees about what the newly allocated memory contains. For that reason it is better to write a function which both allocates and initializes an new object, i.e.:

node* newNode(int v) {
  node* p = (node*) malloc( sizeof(node) );
  // assume malloc never fails
  p-&gt;val = v;
  p-&gt;next = NULL;
  return p;
}


Now use newNode() where you are using malloc() directly.

make_ll

First of all, does your make_ll work for len = 0?

For comparison, here is a recursive solution for make_ll:

node* make_ll(int len) {
  if (len &lt;= 0) {
    return NULL;        // a list of length 0
  } else {
    node *tail = make_ll(len-1);
    node *head = newNode(len);
    head-&gt;next = tail;
    return head;
  }
}


And here is a way I would transform this into a loop which avoids double checking the exit condition:

node* make_ll(int len) {
  if (len &lt;= 0) {
    return NULL;
  }
  node* head = newNode(len);
  node* last = head;
  for (; len &gt; 0; --len) {
    node* n = newNode(len);
    last-&gt;next = n;
    last = n; 
  }
  return head;
}


The idea is to keep track of the last node in the chain so you can update its next field when you create a new node.