Solution for Exercise 08_13-addnodes.c

08_13-addnodes.c

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

struct node {
	int value;
	struct node *next;
};

struct node *add(int v)
{
	struct node *n;

	/* allocate node storage */
	n = malloc( sizeof(struct node) );
	if( n==NULL )
		return(n);

	/* addign values */
	n->value = v;
	n->next = NULL;

	return(n);
}

int main()
{
	struct node *base = NULL;	/* initialize */
	int x,count;

	/* loop to add nodes and values */
	count = 0;
	while(1)
	{
		printf("Enter Node %d value, zero to end: ",count);
		scanf("%d",&x);
		/* end the loop on zero */
		if( x== 0 )
			break;

		/* base must be initially allocated */
		if( base==NULL )
		{
			base = malloc( sizeof(struct node) );
			if( base==NULL )
			{
				fprintf(stderr,"Initial allocation failed\n");
				exit(1);
			}
		}
		else
		{
			base = realloc(base,((count+1)*sizeof(struct node)));
			if( base==NULL )
			{
				fprintf(stderr,"Unable to reallocate\n");
				exit(1);
			}
		}
		(base+count)->value = x;
		(base+count)->next = NULL;
		count++;
	}

	/* output results */
	printf("%d items input\n",count);
	for( x=0; x<count; x++ )
		printf("Node %d: %d\n",
				x,
				(base+x)->value
			  );

	/* clean-up */
	free(base);		/* only need to free the one node */
	return 0;
}

Output

Enter Node 0 value, zero to end: 10
Enter Node 1 value, zero to end: 20
Enter Node 2 value, zero to end: 30
Enter Node 3 value, zero to end: 40
Enter Node 4 value, zero to end: 50
Enter Node 5 value, zero to end: 0
5 items input
Node 0: 10
Node 1: 20
Node 2: 30
Node 3: 40
Node 4: 50

Notes

* You didn't need to create a linked list as this exercise's solution. Just build upon an expanding buffer and use offsets within the buffer to store the various structures.

* The key to know when to use malloc() and when to use realloc() is to initialize the base pointer to NULL, which is done with its declaration: struct node *base = NULL;

* For the endless while loop's first iteration, the value of base is NULL. This setting triggers the if condition, which initially allocates the buffer: if( base==NULL )

* Once variable base is allocated, the else part of the if-else structure takes over, reallocating the buffer to accomodate for a new node: base = realloc(base,((count+1)*sizeof(struct node)));

* The size of the reallocation is set by the value of variable count. This variable is also used to calculate the offset when setting values in the allocated structure: (base+count)->value = x; and (base+count)->next = NULL;

* As the structure is allocated, the -> operator is used.

* Only the value of base needs to be freed at the end of the program: free(base); As all storage is located at the base address, the additional bytes added are removed along with it.