Yes, I have looked in the forums for answers and have found plenty, and am asking about what I could not find. And yes, this is homework, but I need help and my professor has not responded thus far... now on to business.

Description of Goal: Make a Set Data Structure using a singly Linked List. The goal is to read word by word from a text file, and (if it hasn't already been added to the list) add it to the linked list. Simple, right?

My problem: I am not getting the correct outputs. I suspect that my pointers are being screwed up and that is what is messing up my comparisons.

My text file (myFile.txt): "hippo cat dog giraffe hippo kitty rhino cat"

My program output:
"Word is: hippo
ADD1111: hippo
Word is: cat
Compare: cat to: cat
Word is: dog
Compare: dog to: dog
Word is: giraffe
Compare: giraffe to: giraffe
Word is: hippo
Compare: hippo to: hippo
Word is: kitty
Compare: kitty to: kitty
Word is: rhino
Compare: rhino to: rhino
Word is: cat
Compare: cat to: cat
First run: cat"

Result analysis: The program is simply assigning whatever word is read to the head of Linked List. And only compares the buffer to the buffer. This is probably do to the pointers, but I hate pointers and cannot figure it out.

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

struct list_el {
   char *val;
   struct list_el * next;
};

typedef struct list_el item;

void main() {
   item * curr, * head, * curr2;
   int i, isIn = 0, first =0;
   FILE* tFile;
    tFile = fopen("myFile.txt", "r"); // assume the file exists and has data
    char *buf[35];
    head = NULL;
    //curr= head;
    while (!feof(tFile)){
        fscanf(tFile,"%s",buf);
        printf("Word is:   %s   \n",buf);
        isIn = 0;

        if(first==0){ //if first elem in list
            first=1;
            printf("ADD1111:   %s\n  ", buf);
            curr = (item *)malloc(sizeof(item));
            curr->val = buf;
            curr->next  = head;
            head = curr;
        }
        else{
            curr2=curr;
            while(curr){
                if (curr->val == buf){
                printf("Compare:   %s  to:  %s\n", curr->val, buf);
                isIn = 1;
                break;
            }
            curr = curr->next;
            }
            curr=curr2;
            if(isIn == 0){
                printf("ADD:   %s\n  ", buf);
                curr = (item *)malloc(sizeof(item));
                curr->val = buf;
                curr->next  = head;
                head = curr;
            }
        }
      //  curr = head;
    }
    curr=head;
    while(curr) {
      printf("First run:  %s\n", curr->val);
      curr = curr->next;
   }
}

Any help would be appreciated.

Recommended Answers

All 16 Replies

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

typedef struct linked_list_elem {
    char *val;
    struct linked_list_elem* next;
} t_linked_list_elem;

t_linked_list_elem* head = NULL;
t_linked_list_elem* tail = NULL;

// Finds given string in given linked list.
// returns: the t_linked_list_elem matching the string if found,
//          NULL otherwise.
t_linked_list_elem* findItem (const char* string);

// If string already existed in the list, returns the existing item.
// Else adds given string at the end of list and returns the added item.
t_linked_list_elem* addItem (const char* string);

void printList ();

int main() {
    FILE* tFile;
    tFile = fopen ("D:\\Temp\\myFile.txt", "r"); // assume the file exists and has data
    char buf[35];
    //curr= head;
    while (!feof (tFile)) {
        fscanf (tFile, "%s", buf);
        //printf ("BEFORE ADDING: %s", buf);
        //printList ();
        addItem (buf);
        //printf ("AFTER ADDING: %s", buf);
        //printList ();
    }

    printf ("\n\nFinal List\n");
    printList ();

    return 0;
}

t_linked_list_elem* findItem (const char* string) {
    if (head != NULL) {
        t_linked_list_elem* curr = head;
        do {
            if (0 == strcmp (string, curr->val))
                return curr;
            else
                curr = curr->next;

        } while (curr != NULL);
    }
    return NULL;
}

t_linked_list_elem* addItem (const char* string) {
    t_linked_list_elem* existing = findItem (string);
    if (existing != NULL) {
        printf("Trying to add an item (%s) that already existed. Would be ignored.\n", string);
        return existing;
    }

    t_linked_list_elem* newItem = (t_linked_list_elem*) malloc (sizeof (t_linked_list_elem));
    newItem->val = (char*) malloc (strlen (string) * sizeof (char) + 1);
    strcpy (newItem->val, string);
    newItem->next = NULL;

    if (NULL == head) {
        head = newItem;
        tail = head;
    } else {
        tail->next = newItem;
        tail = newItem;
    }

    return tail;
}

void printList () {
    printf ("\nList -- ");
    if (head != NULL) {
        t_linked_list_elem* curr = head;
        do {
            printf ("[%s] ", curr->val);
            curr = curr->next;
        } while (curr != NULL);
    }
    printf (" --\n");
}

--edit--
This is what hte output looks like:

Trying to add an item (hippo) that already existed. Would be ignored.
Trying to add an item (cat) that already existed. Would be ignored.


Final List

List -- [hippo] [cat] [dog] [giraffe] [kitty] [rhino]  --

Well, thank you very much. Doesn't really tell me what I was doing wrong, but does tell me how to do it correctly. When would I need to, and what would I need to, free(deallocate) from memory? Obviously I shouldn't need a delete function for my linked list because if it is a duplicate, it will never be added. But my instructions say:
"For the solution to the problem you first need to design and implement a Set data structure. This set should be used by the solution to the problem to add words from the file and the set will only keep one of each of the added elements.The implementation of the set will need a linked list of set elements. So your solution needs use of pointers as well as dynamic memory allocation and deallocation. Allocation for the set add and deallocation for the set delete operations"

So, what do I need to deallocate? And, in your opinion does the solution you offer(and the one I attempted) meet these requirements? The terminology confuses me sometimes.

Answered some of my own questions(I think). First off, I decided to deallocate the entire list after the printList(); call in the main using deleteList(head); where deleteList() is defined as follows(to be compatible with your code at least):

void deleteList( t_linked_list_elem* ptr )
{
    struct node *temp;

   if( head == NULL ) return;   //empty list cant be deleted
       head = NULL;         //reset
       tail = NULL;          //reset

   while( ptr != NULL ) {   //if more nodes
      temp = ptr->next;     //temp spot for next node when current is free'ed
      free( ptr );          //deallocate space
      ptr = temp;           //next node
   }
}

The question is still asked though, reading my previous post containing part of the assignment, do you believe, using thekashyap's code, this assignment has been satisfied?

This looks wrong.

#
curr->val = buf;
curr->next = head;

This will cause looping.

And use sprintf or strcpy intstead of

curr->val = buf;

Use strcmp to compare the value in buf.

Thank you for your reply. I ended up studying the previous reply and making my own version of his submitted one. So, I am no longer using the original code I posted; however, I do think what you pointed out was the issue. Now I am stuck while trying to parse the input received in the buffer. Technically this has nothing to do with the linked list, but it is a problem. I have the code:

char* parseItem (char* string) {
            int i,newCount=0,lenCount=0;
            char *newStr = (char *) malloc(strlen(string) + 1);

            for(i=0;i<strlen(string);i=i+1){
             //  printf("newStr =  %s ", newStr);
                if(isalpha(string[i])!=0){
                    newStr[newCount]=string[i];
                    newCount= newCount +1;
                    lenCount= lenCount +1;
                }
            }
            char* finalString = (char *) malloc(lenCount +1);
            /*for(i=0; i<lenCount;i=i+1){
              //  printf("Final:   %s Len=  %d ", finalString, lenCount);
                finalString[i]=newStr[i];
            } */
            strncpy(finalString,newStr, lenCount+1);
        return finalString;

}

And I pass it 1 word(literature word, not type) at a time from a rather large text file that is about 3 paragraphs long. I want to take each word and strip any characters from it that are not letters a-z(ex: ',' '.' ':'). The problem I am having is that the first 4 times this is called, the returned string has some random characters on the end(different characters each time). I know this is from a pointer/memory problem, but do not know what I have done wrong. Any help?

Well, thank you very much. Doesn't really tell me what I was doing wrong, but does tell me how to do it correctly. When would I need to, and what would I need to, free(deallocate) from memory? Obviously I shouldn't need a delete function for my linked list because if it is a duplicate, it will never be added. But my instructions say:
"For the solution to the problem you first need to design and implement a Set data structure. This set should be used by the solution to the problem to add words from the file and the set will only keep one of each of the added elements.The implementation of the set will need a linked list of set elements. So your solution needs use of pointers as well as dynamic memory allocation and deallocation. Allocation for the set add and deallocation for the set delete operations"

So, what do I need to deallocate? And, in your opinion does the solution you offer(and the one I attempted) meet these requirements? The terminology confuses me sometimes.

Glad to hear that you still wanna know what's wrong with your code rather than just get it working. :)

I've added comments to your original code with the errors. Reason why I posted the full soln is because I've not done C programming in like 5-8 years, so just wanted to get my hands dirty and there were too many issues in your original post.

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

//KASH: Can do typedef here as well..
struct list_el {
    char *val;
    struct list_el * next;
};

typedef struct list_el item;

void main() {
    item * curr, * head, * curr2;
    int i, isIn = 0, first = 0;
    FILE* tFile;
    tFile = fopen ("myFile.txt", "r"); // assume the file exists and has data
    // KASH: This defines a char**, what you want is a char*
    char *buf[35];
    head = NULL;
    //curr= head;
    while (!feof (tFile)) {
        fscanf (tFile, "%s", buf);
        printf ("Word is:   %s   \n", buf);
        isIn = 0;

        // KASH: Should avoid the variable first, as the first time
        //       head is supposed to be NULL.
        //       So use head == NULL instead of first == 0.
        if (first == 0) { //if first elem in list
            first = 1;
            printf ("ADD1111:   %s\n  ", buf);
            curr = (item *) malloc (sizeof (item));
            // KASH: This copies the pointer (to pointer) i.e. address.
            //       So if you now write something else into the memory
            //       pointed by buf, it'll be visible in curr->val as well.
            //       Because buf and curr->val point to the same location
            //       as both are pointers and not some "string" objects.
            curr->val = buf;
            // KASH: Although following will work because head is NULL
            //       right now, but you should be doing curr->next  = NULL;
            curr->next  = head;
            head = curr;
        }
        else{

            curr2 = curr;
            // KASH: should use curr2 in the following loop and keep curr safe.
            //       IMHO "tail" is better name instead of "curr".
            while (curr) {
                // KASH: Same error as copying. What you're comparing are pointers
                //       what you shoudl be comparing is the contents of memory
                //       locations pointed by these pointers.
                //       See: http://www.cs.cf.ac.uk/Dave/C/node19.html
                //       for list of common string functions.
                if (curr->val == buf) {
                    printf ("Compare:   %s  to:  %s\n", curr->val, buf);
                    isIn = 1;
                    break;
                }
                curr = curr->next;
            }
            curr = curr2;
            if (isIn == 0) {
                printf ("ADD:   %s\n  ", buf);
                // KASH: Actually if you see there is no difference in code whether
                //       you're inserting the first element (lines 32-42) or any
                //       other (lines 79-82). There should be difference. Hope you can
                //       figure that out.
                //
                // Here is my code for same if / else:
                //    if (NULL == head) { // <<-- This is same as your if(first==0)
                //        head = newItem;
                //        tail = head;
                //    } else {
                //        tail->next = newItem;
                //        tail = newItem;
                //	  }

                curr = (item *) malloc (sizeof (item));
                curr->val = buf;
                curr->next  = head;
                head = curr;
            }
        }
        //  curr = head;
    }
    // KASH: With following lines you lose curr.
    curr = head;
    while (curr) {
        printf ("First run:  %s\n", curr->val);
        curr = curr->next;
    }
}


/*

	Even if you had a look at all the warnings that comiler had given you,
	you could've saved some time.

	Here is what gcc gave me:

	-------------- Build: Debug in Test_C ---------------

	Compiling: main.c
	main.c:12: warning: return type of 'main' is not `int'
	main.c: In function `main':
	main.c:22: warning: char format, pointer arg (arg 3)
	main.c:23: warning: char format, pointer arg (arg 2)
	main.c:31: warning: char format, pointer arg (arg 2)
	main.c:38: warning: assignment from incompatible pointer type
	main.c:55: warning: comparison of distinct pointer types lacks a cast
	main.c:56: warning: char format, pointer arg (arg 3)
	main.c:64: warning: char format, pointer arg (arg 2)
	main.c:69: warning: assignment from incompatible pointer type
	main.c:14: warning: unused variable `i'
	Linking console executable: bin\Debug\Test_C.exe
	Output size is 20.89 KB
	Process terminated with status 0 (0 minutes, 0 seconds)
	0 errors, 10 warnings

*/

Thank you for your reply. I ended up studying the previous reply and making my own version of his submitted one. So, I am no longer using the original code I posted; however, I do think what you pointed out was the issue. Now I am stuck while trying to parse the input received in the buffer. Technically this has nothing to do with the linked list, but it is a problem. I have the code:

char* parseItem (char* string) {
            int i,newCount=0,lenCount=0;
            char *newStr = (char *) malloc(strlen(string) + 1);

            for(i=0;i<strlen(string);i=i+1){
             //  printf("newStr =  %s ", newStr);
                if(isalpha(string[i])!=0){
                    newStr[newCount]=string[i];
                    newCount= newCount +1;
                    lenCount= lenCount +1;
                }
            }
            char* finalString = (char *) malloc(lenCount +1);
            /*for(i=0; i<lenCount;i=i+1){
              //  printf("Final:   %s Len=  %d ", finalString, lenCount);
                finalString[i]=newStr[i];
            } */
            strncpy(finalString,newStr, lenCount+1);
        return finalString;

}

And I pass it 1 word(literature word, not type) at a time from a rather large text file that is about 3 paragraphs long. I want to take each word and strip any characters from it that are not letters a-z(ex: ',' '.' ':'). The problem I am having is that the first 4 times this is called, the returned string has some random characters on the end(different characters each time). I know this is from a pointer/memory problem, but do not know what I have done wrong. Any help?

Junk chars at the end of a char*/[] is usually due to missing '\0'.
Whenever you use strncpy() you should explicitly add '\0' at the end of the target string to be sure.

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

int main() {
    char arr[10];

    printf ("--%s--\n", arr);
    arr[5] = '\0';
    printf ("--%s--\n", arr);
    arr[2] = '\0';
    printf ("--%s--\n", arr);
    arr[0] = 'h';
    arr[1] = 'i';
    printf ("--%s--\n", arr);

    char* s1 = "Hello World";
    char* s2 = (char*) malloc (strlen (s1) * sizeof (char) + 5);
    char* s3 = (char*) malloc (strlen (s1) * sizeof (char) + 5);
    printf ("--%s--\n", s1);
    strcpy (s2, s1);
    printf ("--%s--\n", s2);
    strncpy (s3, s1, 5);
    printf ("--%s--\n", s3);
    s3[5] = '\0';
    printf ("--%s--\n", s3);

    return 0;
}

One of my main problems with my original code was that my Linked List was being built backwards. (Null)<-(head->next)<-(head)... it was not smart. However, that second Add portion of the code was supposed to be the same as the initial add when head==null. The difference is that the second add only gets called when the item is not a duplicate. It was allowed to be the same due to the backwards setup of my list.

And with the strncpy, I am still having a problem...

char* parseItem (char* string) {
            int i,newCount=0,lenCount=0;
            char *newStr = (char *) malloc(strlen(string) + 1);

            for(i=0;i<strlen(string);i=i+1){
             //  printf("newStr =  %s ", newStr);
                if(isalpha(string[i])!=0){
                    newStr[newCount]=string[i];
                    newCount= newCount +1;
                    lenCount= lenCount +1;
                }
            }
            char* finalString = (char *) malloc(lenCount +1);
            /*for(i=0; i<lenCount;i=i+1){
              //  printf("Final:   %s Len=  %d ", finalString, lenCount);
                finalString[i]=newStr[i];
            } */
            strncpy(finalString,newStr, lenCount+1);
            finalString[lenCount+1]="\0";
        return finalString;

}

Above causes the program to fail(I believe while deallocating memory), and if I make lenCount+1 into lenCount, it doesnt kill the program, but all the words are cut short once and the final character is replaced by a 'C'. Either way, the first 4 words are still screwed up! Not too sure why.

On a side note:

item* findItem (const char* string) {
    if (head != NULL) {
        item* curr = head;
        int i,j;
        do {
            char* temp1[strlen(string)], temp2[strlen(curr->val)];
            for(i=0;i<strlen(string);i=i+1){
                temp1[i]= tolower(string[i]);
            }
            for(j=0;j<strlen(string);j=j+1){
                temp2[j]= tolower(curr->val[j]);
            }
            if (0 == strcmp (temp1, temp2))
                return curr;
            else
                curr = curr->next;

        } while (curr != NULL);
    }
    return NULL;
}

Above, the code is supposed to weed out any words that are the same, regardless of case, but it still seems to be case-sensitive. What did i do wrong?

Problem still with the parseItem code. Something is causing my newStr to have foreign characters placed throughout the string. It seems to happen upon allocation, but the problem does not occur with EVERY newStr, just the first 4 or so. here is my full code in case anything is being scrambled by something screwed up in another function. Although, if I skip calling parseItem, the results do not have any weird characters in them, so I know the characters are being formed/added in parseItem.

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

typedef struct list_element {
    char *val;
    struct list_element* next;
} item;

item* head = NULL; //start off as null
item* tail = NULL; //start off as null
item* findItem (const char* string); //declare to use later
item* addItem (const char* string);  //declare to use later
//item* parseItem (const char* string);  //declare to use later
item* deleteList(item* head); //declare
void printList ();  //declare
char* parseItem(char* string); //declare

int main() {
    FILE* tFile;
    tFile = fopen ("myFile1.txt", "r"); // assume the file exists and has data
    char buf[35];
    while (!feof (tFile)) {
        fscanf (tFile, "%s", buf); //read word from file
        int sendLen = strlen(buf);
        char* newString = parseItem(buf);
        addItem (newString);  //try to add newly read word into list
        //addItem(buf)
    }
    printList ();  //display total list
    deleteList(head); //deallocate list from memory
    printList (); //test to see if deallocated
    return 0;
}

char* parseItem (char* string) {
            int i,newCount=0,lenCount=0;

         //   char newStr[strlen(string)];
            char* newStr = (char *) malloc(strlen(string)+1);
          //  for(i= 0;i<strlen(string);i++){
          //      newStr[i]=' ';
          //  }


            for(i=0;i<strlen(string);i=i+1){

             printf("newStr =  %s ", newStr);
                if(isalpha(string[i])!=0){
                    newStr[newCount]=string[i];
                    newCount= newCount +1;
                    lenCount= lenCount +1;
                }
            }
           // char* finalString = (char *) malloc(lenCount +1);
            /*for(i=0; i<lenCount;i=i+1){
              //  printf("Final:   %s Len=  %d ", finalString, lenCount);
             //   finalString[i]=newStr[i];
            } */
          //  strncpy(finalString,newStr, lenCount+1);
          //  finalString[lenCount+1]="\0";
        return newStr;

}

/*
// Used to figure out if item is already in list
// Require: string is passed that can be used for comp
// Ensure: the item matching the string, if found, is
//         returned. NULL is returned if not found.
*/
item* findItem (const char* string) {
    if (head != NULL) {
        item* curr = head;
        int i,j;
        do {
          //  char* temp1[strlen(string)], temp2[strlen(curr->val)];
          //  for(i=0;i<strlen(string);i=i+1){
          //      temp1[i]= tolower(string[i]);
          //  }
          //  for(j=0;j<strlen(string);j=j+1){
          //      temp2[j]= tolower(curr->val[j]);
          //  }
            if (0 == stricmp (string, curr->val))
                return curr;
            else
                curr = curr->next;

        } while (curr != NULL);
    }
    return NULL;
}

/*
// Used to add given string item to a linked list
// Require: A valid string is passed
// Ensure: If string already existed in the list, returns the existing item,
//         and does not add a duplicate to the list. Else adds given
//         string at the end of list and returns the added item.
*/
item* addItem (const char* string) {
    item* existing = findItem (string); //creates item (null, or duplicate of string)
    if (existing != NULL) {  //if the item exists already
        //printf("Tried to add an item (%s) that already exists.\n", string);
        return existing;
    }

    item* newItem = (item*) malloc (sizeof (item)); //allocate space for new item
    newItem->val = (char*) malloc (strlen (string) * sizeof (char) + 1); //allocate space for val of newItem
    strcpy (newItem->val, string); // put the string in newItem's val
    newItem->next = NULL; //make item end of list

    if (head == NULL) { //if this is the first item
        head = newItem; //head is the new item,
        tail = head;   //and so is the tail
    } else { //if head already exists
        tail->next = newItem; //former tail's next is newItem
        tail = newItem; //new item is new tail
    }

    return tail;
}


/*
// This function deallocates the memory allocated for the list
// Require: The HEAD of a linked list is passed
// Ensure: Head and Tail will be reset to null, and memory will be
//         deallocated for the entire list.
*/
item* deleteList( item* ptr )
{
    item* temp = NULL; //make a temp item

   if( head == NULL ) return;   //empty list cant be deleted
       head = NULL;         //reset
       tail = NULL;          //reset

   while( ptr != NULL ) {   //if more nodes
      temp = ptr->next;     //temp spot for next node when current is free'ed
      free( ptr );          //deallocate space
      ptr = temp;           //next node
   }
}

void printList () {
    printf ("\nList of all words used in document: \n");
    if (head != NULL) { //if not empty list
        item* curr = head; //start at the head
        do {
            printf (" %s \n", curr->val); //print all items in list
            curr = curr->next; //next item
        } while (curr != NULL);
    }
    printf (" :: End of List. \n");
}

Again. the call to parseItem is my problem.

There is indeed a problem with your parseItem() function.

Check the difference: (I minimized the edits so as to remain recognizable to you)

char* parseItem (char* string) {
    int i, newCount = 0;

    /* FYI: Unrelated to your question: you need to free this up somewhere too */
    char* newStr = (char *) malloc(strlen(string)+1);

    for(i = 0; i < strlen(string); i = i + 1){
        if(isalpha(string[i])!= 0){
            newStr[newCount] = string[i];
            newCount = newCount + 1;
        }
    }

    /* Remember this? */
    printf("newStr =  %s\n", newStr);

    return newStr;
}

Also, avoid declaring variables inside the body of your loops.

Hope that helps. :)

Thank you for the help. (And also, where/how could I free that memory?) The problem is not fixed with your new code. I used the test file:

"This string should have a result of 9 list elements. STRING this should!"

and got the results:

newStr = This─
newStr = string5
newStr = should5
newStr = have─
newStr = a
newStr = result5
newStr = of
newStr = ♀
newStr = list
newStr = elements
newStr = STRING
newStr = this
newStr = should5

List of all words used in document:
This─
string5
should5
have─
a
result5
of

list
elements
STRING
this
:: End of List.

As you can see, there are foreign characters at the end of some words and in place of the number. As soon as I get the parse to work correctly I can simply say if there are no alphas then dont enter into the list, but right now the problem is the foreign characters.

A, sorry about that. I though you were referring to the extra texts that appears while looping inside parseItem().

Actually, based on the code, there should be no non-alpha in the items in your list.
But since you were copying specific characters to your newStr, you forgot to add a trailing '\0' after the last character.

Try to initialize the variable newStr after performing malloc.

char* newStr = (char *) malloc(strlen(string)+1);
memset(newStr, 0x00, strlen(string)+1);

Thank you very much Yan. That worked perfectly! That is the key I have been searching for. I tried to do it manually with a for loop, but that didnt work. By the way, how would you suggest deallocating that memory for newStr?

My current approach is to strcpy(string,newStr) and then free(newStr). Think this works? And could you look through the rest of the code and see if anything is not free'ed? Since the assignment is basically a lesson on memory allocation and deallocation I should probably make sure I have it all correct! :D Thanks again!

Sorry but it doesn't work that way. You have many options on how to do that.

You are working on this data structure:

typedef struct list_element {
    char *val;
    struct list_element* next;
} item;

When allocating an item, normally, you'd allocate space for the structure and then for the members. When deallocating, you'd usually do the reverse: free each member, then the structure itself.

Your code has unnecessary calls to malloc which you can remove.
Think of newStr. Where did it came from and where it is going.

As the Oracle said: everything that has a beginning has an end, Neo. Everything that you malloc'd should also be freed.

Here's a snip of your main():

::
        fscanf (tFile, "%s", buf); //read word from file
        int sendLen = strlen(buf);
        char* newString = parseItem(buf);
        addItem (newString);  //try to add newly read word into list
::

Here's a snip of your parseItem():

char* parseItem (char* string) {
::
    char* newStr = (char *) malloc(strlen(string)+1);
::
    return newStr;

And your addItem():

item* addItem (const char* string) {
::
    item* newItem = (item*) malloc (sizeof (item)); //allocate space for new item

    /*
     * HINT: do you really need to do malloc here?
     * You can actually assign newItem->val with string(parameter) directly
     * To do that you'll need to modify the function into: item* addItem(<your fix here>)
     * If you can do that, you can get rid of the strcpy below as well.
     */
    newItem->val = (char*) malloc (strlen (string) * sizeof (char) + 1); //allocate space for val of newItem
    strcpy (newItem->val, string); // put the string in newItem's val
    newItem->next = NULL; //make item end of list
::

And finally, your deleteList().
I'm quite in a hurry at this point so I can't really check this function. Although I don't feel comfortable with its body (and this is the key part to your deallocation so you should double check this):

item* deleteList( item* ptr )
{
    item* temp = NULL; //make a temp item

   if( head == NULL ) return;   //empty list cant be deleted
       head = NULL;         //reset
       tail = NULL;          //reset

   while( ptr != NULL ) {   //if more nodes
      temp = ptr->next;     //temp spot for next node when current is free'ed
      free( ptr );          //deallocate space
      ptr = temp;           //next node
   }
}

Another tip: try to avoid using global variables. It's not a good practice and they can give you really nasty bugs.

commented: Good work in this thread.. +5

Thank you very much Yan. That worked perfectly! That is the key I have been searching for. I tried to do it manually with a for loop, but that didnt work. By the way, how would you suggest deallocating that memory for newStr?

That's exactly what this post says.

I know thekashyap, but it wasnt working when I just appended "\0" to the end of my entries. For some reason it was still screwing up. The "memset" is for some reason what solved it, even though I tried to manually do the exact same thing after your post explaining it! I don't understand why memset worked but manually doing so didnt...

Thank you very much for you help (both of you). I am not sure if I understand Yan0's last post and I have no idea how to free the newItem's created each call in the addItem function!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.