Of course you can build a linked list or any other data structure without dynamic memory allocation.
You can't, no matter how hard you try, though, build it allocating no memory at all.
Alternative:
Create a global or static memory pool where you can put your objects, imitating the heap/malloc/free. FreeRTOS does something like.
In this situation, you will have a big memory chunk allocated statically since the begining of your program and will be responsible for managing it, returning the correct pointers when a new node is needed and marking that memory as used.
P.S.: I won't question why you want to avoid malloc. I supose you have a good reason for it.
In you program, when you do, in line 20:
node newtemp,root,temp;
You are allocatin thre nodes, one of them, "newtemp".
Then you do in line 28:
newtemp=getnode(i);
It just copies the contents of the returned node over your old "newnode" (controversal, isn't?)
So you do, just bellow:
temp.next=&newtemp;
That sets a pointer that initially comes from "root.next" to your "newnode".
if(root.next==NULL)
Will be "NULL" at first pass, but then, only replace the same contents.
temp=*(temp.next);
{
root=temp;
}
Is, again, copying data from a single allocated object, "*(temp.next)", to another, "temp".
It does not create any new node.
It will work if you do like this:
#include <stdio.h>
typedef struct node
{
int i;
struct node *next;
}
node;
#define MAX_NODES 10
node *create_node( int a )
{
// Memory space to put your nodes. Note that is is just a MAX_NODES * sizeof( node ) memory array.
static node node_pool[ MAX_NODES ];
static int next_node = 0;
printf( "[node *create_node( int a )]\r\tnext_node = %d; i = %d\n", next_node, a );
if ( next_node >= MAX_NODES )
{
printf( "Out of memory!\n" );
return ( node * )NULL;
}
node *n = &( node_pool[ next_node++ ] );
n->i = a;
n->next = NULL;
return n;
}
int main( )
{
int i;
node *newtemp, *root, *temp;
root = create_node( 0 );
temp = root;
for ( i = 1; ( newtemp = create_node( i ) ) && i < MAX_NODES; ++i )
{
temp->next = newtemp;
if ( newtemp )
{
printf( "temp->i = %d\n", temp->i );
printf( "temp->next->i = %d\n", temp->next->i );
temp = temp->next;
}
}
for ( temp = root; temp != NULL; temp = temp->next )
printf( " %d ", temp->i );
return 0;
}
The output:
$ gcc -Wall -o list_no_malloc list_no_malloc.c
$ ./list_no_malloc
[node next_node = 0; i = 0)]
[node next_node = 1; i = 1)]
temp->i = 0
temp->next->i = 1
[node next_node = 2; i = 2)]
temp->i = 1
temp->next->i = 2
[node next_node = 3; i = 3)]
temp->i = 2
temp->next->i = 3
[node next_node = 4; i = 4)]
temp->i = 3
temp->next->i = 4
[node next_node = 5; i = 5)]
temp->i = 4
temp->next->i = 5
[node next_node = 6; i = 6)]
temp->i = 5
temp->next->i = 6
[node next_node = 7; i = 7)]
temp->i = 6
temp->next->i = 7
[node next_node = 8; i = 8)]
temp->i = 7
temp->next->i = 8
[node next_node = 9; i = 9)]
temp->i = 8
temp->next->i = 9
[node next_node = 10; i = 10
Out of memory!
0 1 2 3 4 5 6 7 8 9