Thread: irectories issue iterating through linked linked?

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    6

    irectories issue iterating through linked linked?

    I am coding this program to just save the directory names into a linked list. I THINK have done that successfully (because it prints the strings correctly right after it saves it". My issue now is that my function printData only prints the first element of the list. I guess the "next" element is null. I am not sure why it won't print the whole list. can anyone send me feedback what the issue is iterating through this linked list. I would really appreciate it. Code is below
    Code:
    #include  <sys/types.h>
    #include  <sys/stat.h>
    #include  <dirent.h>
    #include  <ftw.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    
    struct path{
    	char *fp;
    	struct fs* filestats;
    	struct path* next;	
    };
    struct filestats{
    	char *fname;
    	int fsize;
    	struct filestats* next;
    };
    	
    void openSubDir(const char *dName);
    void printData(struct path *end);
    int tcount;
    
    struct path *end;
    struct path *start;
    struct path *temp;
    
    int main(int argc, char *argv[]) {
    tcount=0;
      int storeData(const char *, const struct stat *, int);
      
      ftw(argv[1], storeData, 5); 
    	//start = end;
    	printData(start);
    	//system("PAUSE"); 
    	return 0;
     
    } /* End of main. */
    
    int  storeData(const char *name, const struct stat *sbuf, int ftype){
    		
    	end = malloc(sizeof(struct path)); //allocate space for the record pointer
    	memset(end, 0, sizeof(struct path)); //sets up pointer so rec has some space that can be filled up	
    	
    	if(ftype == FTW_D){ //if the object is a directory
    		if(start == NULL){			
    			start = end;
    			start->fp = malloc(strlen(name));
    			strcpy(start->fp, name);				
    			end = start->next;
    			
    		}
    		else{
    			//end->next = NULL;
    			
    			end->fp = malloc(strlen(name));
    			strcpy(end->fp, name);
    			//printf("%s\n", end->fp);			
    			end= end->next;			
    		}		
    	}
    	tcount++;
    	return 0;
    }
    
    void printData(struct path *endF){
    	struct path *temp;
    	temp = endF;
    	while(temp != NULL){
    		if(temp->fp != NULL){
    			printf("%s\n", temp->fp);
    		}
    		temp = temp-> next;
    	}
    }
    Last edited by coolprogrammer; 05-22-2010 at 06:15 PM. Reason: edit:

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    That's not all of your code, is it?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    6
    sorry forgot to add the other functions

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    One thing I noticed:
    Code:
    int  storeData(const char *name, const struct stat *sbuf, int ftype){
    		
    	end = malloc(sizeof(struct path)); //allocate space for the record pointer
    	memset(end, 0, sizeof(struct path)); //sets up pointer so rec has some space that can be filled up	
    	
    	if(ftype == FTW_D){ //if the object is a directory
    		if(start == NULL){			
    			start = end;
    			start->fp = malloc(strlen(name));
    			strcpy(start->fp, name);				
    			end = start->next;
    Since end is initially memset() to be zeroed out, start will be zeroed out; hence start->next will always be NULL.

    But your real problem is here.
    Code:
    		else{
    			//end->next = NULL;
    			
    			end->fp = malloc(strlen(name));
    			strcpy(end->fp, name);
    			//printf("%s\n", end->fp);			
    			end= end->next;			
    		}
    You just allocated completely new memory for end. Now you've filled end up with some useful data. And then you set end to end->next (which by the same reasoning as above is going to be NULL), and throw away your carefully constructed end!

    I'd suggest you think through how your linked list is working. Grab yourself one of those outmoded sticks with graphite on the end and draw some diagrams. Figure out where your pointers are supposed to be pointing. If you think it through carefully, it's not really that difficult.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Registered User
    Join Date
    Sep 2009
    Posts
    6
    I am a bit closer it is now printing out the first thing in the list some trash not sure what exactly. The only part of the program i modified was the storeData function so I will just post that

    Code:
    int storeData(const char *name, const struct stat *sbuf, int ftype){
    			end = malloc(sizeof(struct path)); //allocate space for the record pointer
    	if(ftype == FTW_D){ //if the object is a directory
    		if(start == NULL){
    			
    			start = end;
    			start->fp = malloc(strlen(name));
    			strcpy(start->fp, name);				
    			end = start;							
    			end = end->next;
    		}
    		else{
    					
    			
    			end->fp = malloc(strlen(name));
    			strcpy(end->fp, name);
    			//printf("%s\n", end->fp);			
    					
    		}		
    	}
    	tcount++;
    	return 0;
    }
    I don't know pointers that well I am kind of just learning everything as I go. Thank you dwks you really lead me in the right direction. I now understand memset and memory allocation a little better. Please lead me further
    Last edited by coolprogrammer; 05-22-2010 at 07:41 PM. Reason: forgot to add something

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You really have to visualize what you're doing. Let's say your start always points to the first element in your list, and end always points to the last (i.e., the element whose next pointer will be NULL). That way you can always access the entire list by starting at start, and adding a new element to the end is easy because you have a pointer to the last element in the list.

    If this is what you want to achieve, then your end pointer should not be NULL -- ever. If it's NULL, then start must be too, and your list must be empty. If the list is nonempty you want end to be non-NULL, so that you can change end->next from NULL to point to your new node.

    Some pseudo-code that might help:
    Code:
    // the list may be empty; it may already have some elements;
    // but either way, we're going to need a new node representing this filename
    // since we're going to add this node to the end of the list, we set its next to NULL
    newnode = malloc(sizeof(*newnode));
    newnode->fp = malloc(strlen(name) + 1);
    strcpy(newnode->fp, name);
    newnode->next = NULL;
    
    if(start == NULL) {
        // if the list is empty, we want start and end to both point to the new node
        start = end = newnode;
    }
    else {
        // add newnode onto the end of the list
        end->next = newnode;
    
        // update end so that it points to the last node, which is now newnode
        // note that newnode->next is already NULL, we ensured that
        end = end->next;  // or end = newnode;
    }
    Note the +1 in the malloc() -- you have to make sure to leave space for the NULL at the end of the string! strlen() does not account for this in its return value. You'll also node that I used sizeof(*newnode) instead of sizeof(struct whatever) in my malloc() call -- this is a good practice in case you ever change the type of newnode. (In that case, if you use sizeof(*newnode) the code will still be correct.)

    As you can see, it's really not as hard as your function makes it look . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Registered User
    Join Date
    Sep 2009
    Posts
    6
    Thank you very much it makes a LOT of sense now. I was able to do this in minutes after this wonderful explanation. :-P

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. linked list issue
    By roaan in forum C Programming
    Replies: 6
    Last Post: 09-01-2009, 01:21 AM
  2. Iterating through a linked list
    By Tom_Arch in forum C Programming
    Replies: 1
    Last Post: 04-24-2009, 08:24 PM
  3. Linked List remove node issue
    By prihod in forum C Programming
    Replies: 1
    Last Post: 04-19-2008, 09:54 AM
  4. Linked list copy constructor issue
    By Craptastic! in forum C++ Programming
    Replies: 1
    Last Post: 08-03-2003, 08:30 PM
  5. need help w/ linked lists
    By MKashlev in forum C++ Programming
    Replies: 11
    Last Post: 08-05-2002, 08:57 PM