Thread: Linked list pointer assignment

  1. #16
    Registered User
    Join Date
    Jun 2006
    Posts
    121
    Hello again,

    Ugh, now I remember why I quit C++ and never looked back after the transition to Java. DS&A with C++ was next to impossible, because I didn't have a firm grasp on pointers. I really need to learn this, though, because I want to do Linux programming and get a deeper O.S. understanding, so, onward. I've commented the code; can someone tell me where my understanding, based on the comments, is wrong? This can not possibly be as difficult as I'm making it out to be.

    Problems at this point:

    -I still have the umlaut displaying in display() as the value of temp->first, and my compiler gripes at this line, saying incompatible implicit declaration of built-in function 'strcpy': strcpy(tail->first, firstName);

    -At the second iteration of insert(), I get an infinite loop that displays the new values that I just inserted. I can't see why this might be happening.

    Thank you!
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    struct personStruct{
    	char first[999];
    	char last[999];
    	struct personStruct *next;
    };
    
    int main(void){
    	struct personStruct *root = NULL;
    	char resp[999];
    	do{
    		char firstName[999], lastName[999];
    		printf("%s", "\nPlease enter a choice, 9 for quit, or any other character to insert: ");
    		fflush(stdout);
    		scanf("%s", resp);
    		if(resp[0] != 9){
    			printf("\n%s", "Please enter the first name: ");
    			fflush(stdout);
    			scanf("%s", firstName);
    			printf("\n%s", "Please enter the last name: ");
    			fflush(stdout);
    			scanf("%s", lastName);
    			insert(&root, firstName, lastName);  //pass a reference to a pointer (two levels of abstraction - why?)
    		}
    	}while(resp[0] != '9');
    	return 0;
    }
    
    void insert(struct personStruct **root, char firstName[], char lastName[]){
    	struct personStruct *tail = malloc(sizeof(struct personStruct));  //new tail pointer
    	printf("\nFirstname = %s", firstName);
    	strcpy(tail->first, firstName);  //get my values into the tail pointer
    	strcpy(tail->last, lastName);
    	tail->next = NULL;
    	if(*root == NULL){  //if the root pointer is null
    		printf("\nRoot = null before");
    		*root = tail;  //make the root pointer the pointer referenced by tail
    		printf("\nAfter, root = %s, %s", (*root)->first, (*root)->last);  //this works - root has the values of tail
    	}
    	else{
    		struct personStruct *temp = *root;  //temp pointer - assign it the value of the root pointer
    		while(temp->next != NULL){  //while not end of list
    			temp = temp->next;  //iterate through
    		}
    		temp->next = tail;  //at end of list, link the new pointer node on the end
    		free(temp);  //free memory
    	}
    	free(tail);  //free memory
    	display(root);  //pass the reference to a pointer
    }
    
    void display(struct personStruct **root){
    	struct personStruct *temp = *root;  //delare a temp pointer, and give it the value of the root pointer
    	int i = 1;
    	while(temp != NULL){  //while not end of list
    		printf("\n%d: %s %s", i, temp->first, temp->last);  //print out current node value
    		fflush(stdout);
    		temp = temp->next;
    		i++;
    	}
    	free(temp);   //free memory
    }

  2. #17
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    To fix the strcpy issue, you need to #include <string.h>. My compiler also gives similar warnings about insert and display (yours should too -- if not, crank up the warnings). C reads top-down, so when you call insert in main, C doesn't know what that funciton looks like yet, so it can't actually check to make sure you're using it correctly. You either need to move the whole function above main (and display needs to be above any place you use it as well), or just put prototypes above main. A prototype is just the first line of a function, with the return type, name and parameters, with a semicolon at the end (and no opening curly brace).:
    Code:
    void insert(struct personStruct **root, char firstName[], char lastName[]);
    I can't reproduce your umlaut problem exactly, but I do get other symptoms that point to the same problem. You shouldn't be calling free in insert or display. You are freeing parts of your list and breaking your list. Free frees memory that malloc allocated for you. You don't just use it with any pointer. You only call free when you're all done with the allocated memory. Once you free the memory, you no longer own it and can never get it back. Accessing it causes undefined behavior, which may be umlauts, infinite loops or seg faults (what I got).

  3. #18
    Registered User
    Join Date
    Jun 2006
    Posts
    121
    Aha, so, only use free() when I want to destroy my list. I didn't realize that that's what I was doing. Also, when I put the function prototypes below into the file just below the include directives, the functions ile shows errors: conflicting types for insert.

  4. #19
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Let's see your new code. You probably borked the prototypes a bit.

  5. #20
    Registered User
    Join Date
    Jun 2006
    Posts
    121
    Hello again,
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    void insert(struct personStruct **root, char firstName[], char lastName[]);
    void display(struct personStruct **root);
    
    
    
    struct personStruct{
    	char first[999];
    	char last[999];
    	struct personStruct *next;
    };
    
    int main(void){
    	struct personStruct *root = NULL;
    	char resp[999];
    	do{
    		char firstName[999], lastName[999];
    		printf("%s", "\nPlease enter a choice, 9 for quit, or any other character to insert: ");
    		fflush(stdout);
    		scanf("%s", resp);
    		if(resp[0] != 9){
    			printf("\n%s", "Please enter the first name: ");
    			fflush(stdout);
    			scanf("%s", firstName);
    			printf("\n%s", "Please enter the last name: ");
    			fflush(stdout);
    			scanf("%s", lastName);
    			insert(&root, firstName, lastName);  //pass a reference to a pointer (two levels of abstraction - why?)
    		}
    	}while(resp[0] != '9');
    	return 0;
    }
    
    void insert(struct personStruct **root, char firstName[], char lastName[]){
    	struct personStruct *tail = malloc(sizeof(struct personStruct));  //new tail pointer
    	printf("\nFirstname = %s", firstName);
    	strcpy(tail->first, firstName);  //get my values into the tail pointer
    	strcpy(tail->last, lastName);
    	tail->next = NULL;
    	if(*root == NULL){  //if the root pointer is null
    		printf("\nRoot = null before");
    		*root = tail;  //make the root pointer the pointer referenced by tail
    		printf("\nAfter, root = %s, %s", (*root)->first, (*root)->last);  //this works - root has the values of tail
    	}
    	else{
    		struct personStruct *temp = *root;  //temp pointer - assign it the value of the root pointer
    		while(temp->next != NULL){  //while not end of list
    			temp = temp->next;  //iterate through
    		}
    		temp->next = tail;  //at end of list, link the new pointer node on the end
    		free(temp);  //free memory
    	}
    	free(tail);  //free memory
    	display(root);  //pass the reference to a pointer
    }
    
    void display(struct personStruct **root){
    	struct personStruct *temp = *root;  //delare a temp pointer, and give it the value of the root pointer
    	int i = 1;
    	while(temp != NULL){  //while not end of list
    		printf("\n%d: %s %s", i, temp->first, temp->last);  //print out current node value
    		fflush(stdout);
    		temp = temp->next;
    		i++;
    	}
    	free(temp);   //free memory
    }

  6. #21
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Ahh, move them between the definition of personStruct and the definition of main. Since those functions prototypes user personStructs, they must know about them before hand.

  7. #22
    Registered User
    Join Date
    Jun 2006
    Posts
    121
    Aha, that makes sense (top-down). Thank you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. assignment of node in linked list
    By nutzu2010 in forum C Programming
    Replies: 8
    Last Post: 03-28-2011, 10:29 AM
  2. next pointer in linked list
    By c_weed in forum C++ Programming
    Replies: 5
    Last Post: 11-15-2010, 06:42 PM
  3. please help..linked list homework assignment due tomorrow..
    By rocketman03 in forum C Programming
    Replies: 2
    Last Post: 11-23-2008, 06:32 PM
  4. Warnings with Pointer In Linked List
    By charIie in forum C Programming
    Replies: 8
    Last Post: 12-27-2007, 05:18 PM
  5. Linked list pointer error
    By pattop in forum C Programming
    Replies: 1
    Last Post: 05-18-2004, 03:30 PM