Thread: Help free structs and pointer.

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    103

    Help free structs and pointer.

    Hey guys I'm having troubles understanding how to free a list of linked structs.

    For simplicity reason we'll say that my struct has a value and a ptr to the next item. Here is waht I have but when I compile it, it doesn' t do anything.

    Code:
    void removePtr(LIST_ELEM *pHead, int loc){
    
    	LIST_ELEM *ptr;
    	LIST_ELEM *tmpPtr;
    	int size = sizeOf(pHead);
    	int i = 0;
    
    	for(ptr = pHead; pHead != NULL; ptr++){
    	   
    	    if( loc == 0){
    		tmpPtr = pHead;
    		pHead = ptr->pNext;
    		free(tmpPtr);
    	     }
    	    else if(loc = size-1){
    		LIST_ELEM *ptrB4 = nodeB4(pHead,loc);
    		ptrB4->pNext = NULL;
    		free(ptr);
    		}		
    				
    	    else if( i == loc){
    		LIST_ELEM *ptrB4 = nodeB4(pHead,loc);
    		tmpPtr = ptr;
    		LIST_ELEM *ptrAfter = (tmpPtr->pNext);
    		ptrB4->pNext = ptrAfter;
    		free(tmpPtr);
    		}
    	i++;
    	}
    }
    remove takes in the head of the list and the location/index where we want the item removed.

    nodeB4 returns the item that come before the item we want to remove. Any ideas?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by TaiL View Post
    Code:
    void removePtr(LIST_ELEM *pHead, int loc){
    
    	LIST_ELEM *ptr;
    	LIST_ELEM *tmpPtr;
    	int size = sizeOf(pHead);
    	int i = 0;
    
    	for(ptr = pHead; pHead != NULL; ptr++){
    	   
    	    if( loc == 0){
    		tmpPtr = pHead;
    		pHead = ptr->pNext;
    		free(tmpPtr);
    	     } //if you pass in loc=0, won't you kill the entire list as you go through the loop?
    	    else if(loc = size-1){ //this is an assignment, not a comparison (also, why is it a special case?
    		LIST_ELEM *ptrB4 = nodeB4(pHead,loc);
    		ptrB4->pNext = NULL;
    		free(ptr);
    		}		
    				
    	    else if( i == loc){ //because of the assignment above, this never happens
    		LIST_ELEM *ptrB4 = nodeB4(pHead,loc);
    		tmpPtr = ptr;
    		LIST_ELEM *ptrAfter = (tmpPtr->pNext);
    		ptrB4->pNext = ptrAfter;
    		free(tmpPtr);
    		}
    	i++;
    	}
    }
    See comments in code.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    103
    Hm if its equal to 0 that would mean we want to remove the head of the "list" right? So then we'd have to change where the head of the list is which it then next item.


    checking to see if its the last item of the list allows us to change the 2nd to last item of the list to point to null.

    I think thats what I was going for.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I agree that the head is a special case (although the tail isn't). But you can't do this inside the loop -- otherwise you're going to delete the head of the list; and then you're going to delete the head of the list; and then you're going to delete the head of the list; and then....

    But I just now noticed the reason your for-loop never happens in the first place: pHead != NULL is never true.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I actually took a big red marker and drew == above the function keys.

    Nothing to do with the iching tho.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    103
    above the function keys?

    wouldn't I need pHead!=Null so it could iderate through it all to find the item at the location?

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by TaiL View Post
    above the function keys?

    wouldn't I need pHead!=Null so it could iderate through it all to find the item at the location?
    Is pHead supposed to change through the loop?

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    103
    HEY TABSTOP!! Sorry its suppose to be ptr not pHead. =)thnx

  9. #9
    Registered User
    Join Date
    Oct 2008
    Posts
    103
    so after fixing that error. Here's what i have
    Code:
    
    void removePtr(LIST_ELEM *pHead, int loc){
    
    	LIST_ELEM *ptr;
    	LIST_ELEM *tmpPtr;
    	int size = sizeOf(pHead);
    	int i = 0;
    
    	for(ptr = pHead; ptr != NULL; ptr++){
    	   
    	    if( loc == 0 && (size==0)){
    		tmpPtr = pHead;
    		pHead = ptr->pNext;
    		free(tmpPtr);
    		printf("The list is now empty.");
    	     }		
    	   else if( loc == 0){
    		tmpPtr = pHead;
    		pHead = ptr->pNext;
    		free(tmpPtr);
    	     }	
    	    else if( i == loc){
    		LIST_ELEM *ptrB4 = nodeB4(pHead,loc);
    		tmpPtr = ptr;
    		LIST_ELEM *ptrAfter = (tmpPtr->pNext);
    		ptrB4->pNext = ptrAfter;
    		free(tmpPtr);
    		}
    	i++;
    	}
    }
    Checking the first two cases gives me a seg fault and checking the last error gives me a
    Code:
     glibc detected *** a.out: free(): invalid pointer:
    errror.

    going home so I'll be back tomorrow =(

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Man I really didn't look at your for-loop. "ptr++" makes no sense in a linked list. Use "ptr=ptr->next" instead.

  11. #11
    Registered User
    Join Date
    Oct 2008
    Posts
    103
    lol you know I don't know why i did that I originally had pNext instead of p++ =\
    but for some reason it still doesn't seem to work giving me the same glibc error.
    Last edited by TaiL; 10-04-2008 at 04:45 PM.

  12. #12
    Registered User
    Join Date
    Oct 2008
    Posts
    103
    So it executes now but it doesn't free anything.


    Code:
    if( loc == 0 && (size==1)){
    		tmpPtr = ptr;  // points tmpPtr to where Ptr is pointing
    		pHead = NULL;//since its our only item we'll set pHead to point to null
    		free(tmpPtr);// we then free tmpPtr
    		printf("The list is now empty.");//lets usr know item was deleted.
    		
    	     }

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I don't know what you think size==1 is supposed to do, but size will always equal 4 (regardless of how many things there are on the list, et cetera).

  14. #14
    Registered User
    Join Date
    Oct 2008
    Posts
    103
    sorry, size is equal to to a value returned by a method which returns the actual size of my list.

  15. #15
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Okay, yes I see the capital O this time. So why do you say it doesn't free anything? If you mean the assigning of pHead to NULL isn't seen in the calling function, well, that's true. Changes made in the function stay in the function.

    If you want to be able to change the value of the pointer, you need to pass in the address of the pointer (so that you would have a pointer-to-pointer-to-LIST_ELEM).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. using free with a casted pointer..
    By smoking81 in forum C Programming
    Replies: 3
    Last Post: 10-01-2008, 04:50 PM
  2. pointer to array of structs
    By Luken8r in forum C Programming
    Replies: 2
    Last Post: 01-08-2008, 02:05 PM
  3. pointer to array of structs
    By Luken8r in forum C Programming
    Replies: 4
    Last Post: 01-02-2008, 11:20 AM
  4. Replies: 41
    Last Post: 07-04-2004, 03:23 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM