I've been trying to code a link list in c and though it seems fairly straight forward I'm getting strange output.
My link list nodes:
struct OBJECT {
int Status;
struct OBJECT *P_LINK;
struct OBJECT *N_LINK;
struct VALUE *P_VALUE;
};
Link list
struct llist {
struct OBJECT *head;
struct OBJECT *tail;
int size;
};
Constructors for LL and OBJECT
struct OBJECT * new_OBJECT(struct VALUE *item,int stat) {
struct OBJECT *node;
node = (struct OBJECT *) malloc (sizeof (struct OBJECT));
if (node == NULL) {
fprintf(stderr, "new_OBJECT() : malloc error");
return NULL;
}
node->P_VALUE = item;
node->P_LINK = 0;
node->N_LINK = 0;
node->Status = stat;
printf(" Object value is: %s\n\n",node->P_VALUE->VALUE);
return node;
};
struct llist * new_list() { /* function name */
struct llist *lst;
lst = (struct llist *) malloc(sizeof(struct llist));
/* malloc returns 0 on error */
if (lst == NULL) {
fprintf(stderr, "new_list() : malloc error");
return NULL;
}
/* initialize the list size and the list head */
lst->head = (struct OBJECT *) calloc( 1, sizeof(struct OBJECT ) );
lst->tail = (struct OBJECT *) calloc( 1, sizeof(struct OBJECT ) );
lst->size = 0;
return lst;
};
Insert function
struct llist * l_insert_H(struct llist *ls, char type, char * value, int status) {
struct OBJECT *node;
struct VALUE *val;
/* get a new OBJECT && new VALUE */
val= new_VALUE(type, value);
node = new_OBJECT(val,status);
if (node == NULL) { return 0; }
//l_append(ls,node);
/* insert the node at the head of the list */
if(ls->size==0){
ls->head=node;
ls->tail=node;
printf("\n******printing ls with 1st element\n");
l_print(ls);
}
else{
ls->tail->N_LINK=node;
node->P_LINK=ls->tail;
ls->tail=node;
l_print(ls);
}
(ls->size)++;
printf("Adding value: %s: %d\n\n",node->P_VALUE->VALUE,ls->size);
return ls;
};
My main()
main (int argc, char *argv[])
{
extern TKN get_token(FILE *);
TKN Token;
FILE *Input;
int TokenNr = 1, LineNr = 1, Done = 0, k;
Input = fopen(argv[1], "r");
struct llist *Ids;
struct llist *Numbers;
struct llist *Seps;
struct llist *Unknown;
Ids = new_list();
Numbers = new_list();
Seps = new_list();
Unknown = new_list();
char * tmp;
while (!Done)
{
Token = get_token( Input );
switch (Token.Code)
{
case 'I':
{
/* process identifier Ids < 20 char I, length string*/
printf("(%d,%d) Symbol: Identifier %s\n",TokenNr, LineNr,Token.String);
tmp=Token.String;
l_insert_H(Ids, 'I', tmp, 0);
printf("\n\n^^^^^back to main loop\n\n");
l_print(Ids);
TokenNr = TokenNr+1;
break;
}
case 'N':
{
//process integer number 'N'
printf("(%d,%d) Symbol: Integer number %s\n",TokenNr,LineNr,Token.String);
printf("***************::%s***************\n",Token.String);
l_insert_H(Numbers, 'N', Token.String, 0);
TokenNr = TokenNr+1;
break;
}
case 'F':
{
// process real number
printf("(%d,%d) Symbol: Real number %s\n",TokenNr,LineNr, Token.String);
printf("***************::%s\n\n***************\n",Token.String);
l_insert_H(Numbers, 'F', Token.String, 0);
TokenNr = TokenNr+1;
break;
}
case 'W':
{
printf("White symbol received\n");
l_insert_H(Seps, 'W', Token.String, 0);
TokenNr = TokenNr+1;
break;
}
case 'T':
{
printf("Terminators received\n");
l_insert_H(Seps, 'T', Token.String, 0);
TokenNr = TokenNr+1;
break;
}
case 'R':
{
printf("Relation symbol received\n");
l_insert_H(Seps, 'R', Token.String, 0);
TokenNr = TokenNr+1;
break;
}
case 'S':
{
printf("Separators symbol received\n");
l_insert_H(Seps, 'S', Token.String, 0);
TokenNr = TokenNr+1;
break;
}
case 'L':
{
printf("New line symbol received\n");
l_insert_H(Seps, 'L', Token.String, 0);
LineNr = LineNr+1;
TokenNr = 1;
}
case 'U':
{
if (Token.String[0] == 'Z'){
//l_insert_H(Seps, 'Z', Token.String, 0);
Done = 1;
}
else
printf("Unprintable character discovered\n");
break;
TokenNr = TokenNr+1;
}
case 'O':
{
printf("(%d,%d) Symbol: Separator %s\n",TokenNr,LineNr,Token.String);
l_insert_H(Seps, 'O', Token.String, 0);
TokenNr = TokenNr+1;
break;
}
case 'E':
{
printf("Error condition: %s\n", Token.String);
l_insert_H(Unknown, 'E', Token.String, 0);
TokenNr = TokenNr+1;
break;
}
}
} /* end while */
printf("\n\n******************* Printing lists ************************\n\n");
l_print(Ids);
printf("1. %s\n2. %s\n3. %s\n",Ids->head->P_VALUE->VALUE, Ids->head->N_LINK->P_VALUE->VALUE, Ids->head->N_LINK->N_LINK->P_VALUE->VALUE);
/*
l_print(Numbers);
l_print(Seps);
l_print(Unknown);
*/
}
I've checked my logic and it seems to be right but up on the ith insertion all my previous i-1 nodes are lost and a link list of i copies of the ith node is returned such that i<=2. I'm very confused by this, since I never loop through all the nodes of the LL unless I'm printing them and that doesn't effect the values, yet I'm getting multiple copies of the node being added. Any help would be greatly appreciated.