user1411893
user1411893

Reputation: 628

Linked list not printing/adding properly in C

This is just a rough code,so there are no free(s) in there yet. I am just trying to figure out where its messing up my linked list.

The purpose of the following function is to accept something like :

add 1 2

or

add 1 "some quote" maybe more stuff

and make a linked list with elements.. in first case:

[add]->[1]->[2]

in second case:

[add]->[1]->["some quote" maybe more stuff]

I know that it is actually doing the steps, because the 'count/total' is right in the output. However when I try to iterate through the linked list, it only prints the first element.

typedef struct command{
    char* args;
    struct command *next;
}command;
typedef struct commands_list{
    command *head;  /*Start of the queue*/
    int total;  /*Total commands passed*/
}commands_list;

commands_list* process_command(char *command){
    char curr_char;                 /*Keeps track of current character*/
    int start_pos;
    int i;
    int len;    

    /*Length of user input*/
    int quote=0;
    int empty =1;
    commands_list *commands;
    struct command *conductor;

    len = strlen(command);              /*Calculate length*/    
    /*Initialize the List*/
    commands=malloc(sizeof(commands_list));         /*Allocate memory for the linked list*/
    commands->head = malloc(sizeof(struct command));
    conductor = commands->head;

    for(i=0,start_pos=0;i<strlen(command);i++){
        curr_char = command[i];
        if (empty==0){
            conductor = malloc(sizeof(struct command));
        }
        if (curr_char == ' '){      /*If there was a space found copy the stuff before the space*/
            if ( i>0 && command[i-1]==' ') {
                start_pos++;
                continue;
            }
            conductor->args = malloc(i-start_pos+1*(sizeof(char))); /*Allocate memory for the word to be copied*/
            strncpy(conductor->args,command+start_pos,i-start_pos); /*Copy the word/command to the memory allocated*/
            conductor->args[i-start_pos+1]='\0';            /*Add null terminator at end*/
            commands->total++;              /*Increase total # of commands*/
            conductor=conductor->next;          /*Conductor points to the first element now*/
            start_pos =i+1;
            if (empty==1){
                empty=0;
            }
        }
        else if (curr_char == '\"'){        /*If a quote was found, copy the rest of the string and exit loop*/
            conductor->args = malloc(len-i+1*(sizeof(char)));
            strncpy(conductor->args,command+i,len-i);
            conductor->args[len-i+1]='\0';
            conductor->next=NULL;
            commands->total++;
            quote=1;
            //empty_queue = 0;
            conductor = conductor->next;
            if (empty==1){
                empty=0;
            }
            break;
        }
    }
    if (quote==0){                  /*If there was no quote in the string, get the last element*/
        if (empty==0){
            conductor = malloc(sizeof(struct command));
        }
        conductor->args = malloc(len-start_pos+1*(sizeof (char)));
        strncpy(conductor->args,command+start_pos,len-start_pos);
        conductor->args[len-start_pos+1]='\0';
        conductor->next=NULL;
        commands->total++;
    }   /*Finish find quote*/
    printf("%d commands found\n",commands->total);
    //free(conductor);
    return commands;    
}

And a temporary method that I am using to print the linked list:

int print_list(commands_list **headNode){
    commands_list *top = *headNode;
    struct command *temp = top->head;           /*Temporary variable for command*/
    while(temp!=NULL){
        printf("I was here to print: [%s]\n",temp->args);
        temp = temp->next;
    }
    printf("It was all null\n");

    free(temp);
}

Thanks

Upvotes: 1

Views: 147

Answers (2)

copper.hat
copper.hat

Reputation: 258

There are many problems in the code that make it hard to debug.

The main issue is how you add a struct command * to the end of the list. The line

        conductor=conductor->next;

will just assign conductor to NULL (or whatever malloc did). You never assign conductor->next to anything.

When you malloc a new struct command *, you need to update the old conductor->next to the newly allocated element. So instead of:

        conductor = malloc(sizeof(struct command));

You need something like:

        struct command *tmp = malloc(sizeof(struct command));
        conductor->next = tmp;
        conductor = tmp;

Also, it might help your debug if you added the line conductor->args = "not allocated yet #1"; after the last line above. This is gross, and should not appear in production code, but will help you debug your issues.

Upvotes: 1

Clifford
Clifford

Reputation: 93476

If it prints only the first element, you must conclude that the next member of the first element is NULL; conductor is assigned conductor->next but conductor->next itself is never assigned anything other than NULL.

When adding to the end, the next member of the current end must be assigned the address of the new item. It does not appear that that is what is happening.

I strongly suggest that you use a symbolic debugger to analyse this code. It will allow you to step through each line while monitoring the variable state.

Upvotes: 1

Related Questions