How to free Single linked List Nodes with dynamic char* fields???

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • sirsnorklingtayo
    New Member
    • Jan 2007
    • 26

    How to free Single linked List Nodes with dynamic char* fields???

    hi guys please help about Linked List,

    I'm having trouble freeing the allocated memory of a single linked list node with a dynamic char* fields, it doesn't freed up if I use the FREE() function in C.. But if I try to use a single linked list with a static char array fields I can free the memory allocated with out any problems using the FREE(). So, why freeing a single linked list with dynamic char* is hard and why the FREE() function is not working??? You can see the difference if you monitor the Memory and Swap in your OS System Monitor.

    Thanks in advance!

    Here is my code

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    /*
    	Base Platform OS: Ubuntu 7.04
    
    	C Compiler      : gcc (GCC) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
    
    	How I compile  : 
    			
    			terminal$ gcc -Wall main.c -o main
    
    	Problem         : Freeing the allocated memory of Dynamic Char* in a Single Linked 
    			  List is not working I don't know why.. But if I use the Static Char 
    			  Array and free the Single Linked List Nodes, the memory and swap 
    			  allocated are freed up successfuly.
    
    	Note		: To monitor the behaviour of the Memory and the Swap memory of the OS 
    			  use the System Monitor 
    
    */
    
    typedef struct ptable
    {
      char *data1;//[50];	
      char *data2;//[50];
      char *data3;//[50];
      char *data4;//[50];
      int len;
      struct ptable *next;
    }pTable;
    
    /* function prototypes */
    void freemem(pTable **pointer);
    void drop_rec(char * rec);
    int display(pTable *pointer);
    
    /* Free the allocated memory of Dynamic Char* */
    void drop_rec(char * rec)
    {
    	free(rec);
    	rec = NULL;
    return;
    }
    
    int main()
    {
    	long i = 0;
    	char tdata[50] = "";
    
    	pTable * ptable;
    	pTable * header;
    	pTable * pointer;
    
    	memset(tdata,0,50);        
    
            /* create a list of data */
    	for(i=0;i<=1000000;i++)
    	{
    		/* clean tdata first */
    		memset(tdata,0,50);
    
    		/* create data to be inserted */
    		sprintf(tdata,"0000000%ld",i);
    
    		/* allocate memory */
    		ptable = (pTable *) malloc(sizeof(pTable));	
    		if(ptable == NULL){
    			printf("Unable to allocate memory.\n");
    			break;
    			return -1;
    		}
    
    		/* I should also check these,if the memory has been allocated successfuly */
                    /* but I want to make this code short just to understand quickly*/
    
    		ptable->data1 = malloc(strlen((char *) tdata)+1); /* set the size to be allocated */
    		ptable->data2 = malloc(strlen((char *) tdata)+1); /* set the size to be allocated */
    		ptable->data3 = malloc(strlen((char *) tdata)+1); /* set the size to be allocated */
    		ptable->data4 = malloc(strlen((char *) tdata)+1); /* set the size to be allocated */
    
    		ptable->next = NULL;
    
    		if(header == NULL)
    			header = ptable;
    		else
    			pointer->next = (pTable *) ptable;
    		
    		/* Assign some values */
    		sprintf(ptable->data1,"%s",(char *) tdata);
    		sprintf(ptable->data2,"%s",(char *) tdata);
    		sprintf(ptable->data3,"%s",(char *) tdata);
    		sprintf(ptable->data4,"%s",(char *) tdata);
    
    		pointer = ptable;
    	
    	}	
    
    	pointer = header;
           
            /* displaying the records will take some time */
    	/* display(pointer); */
    
    	printf("Press Any Key to release allocated memory . . .\n");
    	getchar();
    	printf("freeing allocated memory . . .\n");	
    	printf("Look at the System Monitor if the Memory and Swaps are being freed.\n");
    	freemem(&pointer); /* free memory (this one is not working I don't know) */
    	freemem(&header);  /* free memory (this one is not working I don't know) */
    	printf("Memory freed up! Done.\n");
    	printf("Press Any Key to close.\n");
    	getchar();
    
    	/* then it only freed up the allocated memory 
    	   if the program is terminated */
    
    	return 0;
    }
    
    /* free up memory doesn't work */
    void freemem(pTable **pointer)
    {
    	pTable *ptr,*next;
    	ptr = *pointer;
    
    	while(ptr != NULL)
    	{
    		/* save the next node */
    		next =(pTable*) ptr->next;		
    
    		/* defective part of my freemem (NOT Working)*/
    		/* I used the FREE() function, same result doesn't work*/
    		drop_rec(ptr->data1); /* free the char* field */
    		drop_rec(ptr->data2); /* free the char* field */
    		drop_rec(ptr->data3); /* free the char* field */
    		drop_rec(ptr->data4); /* free the char* field */
    
    	        free(ptr);  /* free node */
    		ptr = next; /* get the next node to be freed up*/
    	}
    	/* remove the handle*/  
    	ptr = NULL;
    	return;
    }
    
    int display(pTable *pointer)
    {
    	pTable *ptr;
    	
    	ptr = pointer;
    	printf("\n\n");
    	/* loop and display records */
    	while(ptr != NULL)
    	{	
    		printf("************\n");
    		printf("Data1 [%s]\n",ptr->data1);
    		printf("Data2 [%s]\n",ptr->data2);
    		printf("Data3 [%s]\n",ptr->data3);
    		printf("Data4 [%s]\n",ptr->data4);
    		ptr = (pTable*) ptr->next;
    		printf("************\n");
    	}
    	printf("\n\n");
    return 0;
    }
  • gpraghuram
    Recognized Expert Top Contributor
    • Mar 2007
    • 1275

    #2
    It should work.
    Try replacing the function drop_rec with free(ptr) and ptr=NULL; inside the code itself.

    Raghu

    Comment

    • sirsnorklingtayo
      New Member
      • Jan 2007
      • 26

      #3
      Originally posted by gpraghuram
      It should work.
      Try replacing the function drop_rec with free(ptr) and ptr=NULL; inside the code itself.

      Raghu
      Yes Sir, I did this one before and it doesn't work with dynamic char* but when I'm using the static char array it works well. I tried it again just to verify it and here is the new code for freemem() function as suggested. I don't know if there is a hardware issues or OS issues but I tried to use another computer with same OS but with different hardware and the result is still problematic.

      Code:
      /* free up memory doesn't work */
      void freemem(pTable **pointer)
      {
      	pTable *ptr,*next;
      	ptr = *pointer;
      
      	while(ptr != NULL)
      	{
      		/* save the next node */
      		next =(pTable*) ptr->next;		
      		/* Only works if I change the fields char* to static array char[50]*/
      		free(ptr);	// replace drop_rec function with FREE	
      		ptr = NULL; // release handle
      
      		ptr = next; /* get the next node to be freed up*/
      	}
      	
      	return;
      }

      Comment

      • gpraghuram
        Recognized Expert Top Contributor
        • Mar 2007
        • 1275

        #4
        How are u saying that free is not working?

        Raghu

        Comment

        • sirsnorklingtayo
          New Member
          • Jan 2007
          • 26

          #5
          Originally posted by gpraghuram
          How are u saying that free is not working?

          Raghu
          Ok, free() is not working if I freeing the allocated memory of a Single Linked List with dynamic array char* field. On the other hand, free() is working if I freeing the allocated memory of a Single Linked List with static array char[]. Yes, I agreed with you that the previous suggestion you mentioned should work. But in this case I don't know what is going on I can not see the problem. If you want may be you could try to run my program and see what I'm trying to say.

          I remove my code here, because I think I'm violating the posting rules here
          Last edited by sirsnorklingtayo; Jun 9 '08, 04:07 AM. Reason: too much codes

          Comment

          • sirsnorklingtayo
            New Member
            • Jan 2007
            • 26

            #6
            You will notice that there will be no compilation error, and while running the program will run smoothly no crashes or memory fault will happen. You can open the System Monitor to see what's going on to the Memory and Swap, you'll see the difference.

            Thanks

            Comment

            • gpraghuram
              Recognized Expert Top Contributor
              • Mar 2007
              • 1275

              #7
              Originally posted by sirsnorklingtay o
              You will notice that there will be no compilation error, and while running the program will run smoothly no crashes or memory fault will happen. You can open the System Monitor to see what's going on to the Memory and Swap, you'll see the difference.

              Thanks
              I am not very sure that this is the right way to find whether the free is working.
              There should be a better way of doing this...
              Other experts please comment on this

              Raghu

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                How do you know that free is not working? How do you know it has not returned the memory to the heap?

                Comment

                • JosAH
                  Recognized Expert MVP
                  • Mar 2007
                  • 11453

                  #9
                  If you allocate a list node and allocate again for a char* that is part of that list node
                  then you have to free them both in opposite direction: first free that char* part of
                  the list node and then free the node itself.

                  kind regards,

                  Jos

                  Comment

                  • sirsnorklingtayo
                    New Member
                    • Jan 2007
                    • 26

                    #10
                    I can see it using the System Monitor of Linux Ubuntu, there is a real-time graph that can tell how much memory are being allocated. And so when I'm running my sample program, the Memory and Swap Graph telling me that my memory is hitting up to 40% - 50% of usage. You'll notice in my code that I'm pausing the program and ask the user to press any key to free some memory so that the user has enough time to see the Memory Graph declining, it means the memory are being deallocated and return it to OS. But this scenario is only working and it happens in real time when deallocating the memory allocated by a "Single Linked List Node with static array char", so this scenario should also happen when deallocating a "Single Linked List Node with Dynamic Array Char*" but it did not and it only means that the memory are still allocated and not being freedup by FREE() function. So what do you think Sirs?

                    Best Regards,
                    Norman

                    Comment

                    • sirsnorklingtayo
                      New Member
                      • Jan 2007
                      • 26

                      #11
                      Originally posted by JosAH
                      If you allocate a list node and allocate again for a char* that is part of that list node
                      then you have to free them both in opposite direction: first free that char* part of
                      the list node and then free the node itself.

                      kind regards,

                      Jos
                      Yes Sir, I did this also deallocate first the fields then next is the list node pointer. Like the code below taken from above code

                      Code:
                      #
                      /* free up memory doesn't work */
                      
                      void freemem(pTable **pointer)
                      {
                          pTable *ptr,*next;
                          ptr = *pointer;
                       
                          while(ptr != NULL)
                          {
                              /* save the next node */
                              next =(pTable*) ptr->next;   
                              /* defective part of my freemem (NOT Working)*/
                      
                              /* I used the FREE() function, same result doesn't work*/
                      
                              drop_rec(ptr->data1); /* free the char* field */
                              drop_rec(ptr->data2); /* free the char* field */
                              drop_rec(ptr->data3); /* free the char* field */
                              drop_rec(ptr->data4); /* free the char* field */
                              free(ptr);  /* free node */
                      
                              ptr = next; /* get the next node to be freed up*/
                           }
                          /* remove the handle*/ 
                      
                          ptr = NULL;
                          return;
                      }
                      And this is the reason why I raised this problem here, because in the first place freeing a memory should never be a problem because FREE() function will handle it.

                      Best Regards,
                      Norman

                      Comment

                      • JosAH
                        Recognized Expert MVP
                        • Mar 2007
                        • 11453

                        #12
                        And what 'does not work' mean?

                        kind regards,

                        Jos

                        Comment

                        • Banfa
                          Recognized Expert Expert
                          • Feb 2006
                          • 9067

                          #13
                          Originally posted by sirsnorklingtay o
                          I can see it using the System Monitor of Linux Ubuntu, there is a real-time graph that can tell how much memory are being allocated. And so when I'm running my sample program, the Memory and Swap Graph telling me that my memory is hitting up to 40% - 50% of usage. You'll notice in my code that I'm pausing the program and ask the user to press any key to free some memory so that the user has enough time to see the Memory Graph declining, it means the memory are being deallocated and return it to OS. But this scenario is only working and it happens in real time when deallocating the memory allocated by a "Single Linked List Node with static array char", so this scenario should also happen when deallocating a "Single Linked List Node with Dynamic Array Char*" but it did not and it only means that the memory are still allocated and not being freedup by FREE() function. So what do you think Sirs?
                          I think that this is extremely circumstantial evidence that the memory is not freed. I do not know Ubuntu (or any other Linux) well but I would want an exact description of what is being monitored before I took this as proof of free not working.

                          In the context (I assume you are using gcc) I think it is far more likely that you either have a mistake in your program or are mis-interpreting the data than free from the gcc standard library or Ubuntu has an error in it.

                          Comment

                          • sirsnorklingtayo
                            New Member
                            • Jan 2007
                            • 26

                            #14
                            Originally posted by JosAH
                            And what 'does not work' mean?

                            kind regards,

                            Jos
                            The memory is not released/deallocate when using the FREE() function. And there are no warning or error messages.

                            Comment

                            • sirsnorklingtayo
                              New Member
                              • Jan 2007
                              • 26

                              #15
                              Originally posted by Banfa
                              I think that this is extremely circumstantial evidence that the memory is not freed. I do not know Ubuntu (or any other Linux) well but I would want an exact description of what is being monitored before I took this as proof of free not working.

                              In the context (I assume you are using gcc) I think it is far more likely that you either have a mistake in your program or are mis-interpreting the data than free from the gcc standard library or Ubuntu has an error in it.
                              Ok just give me some time to check this again I'll use different OS like Windows and lets see if I will be having a same problem again. Yes, actually that is my first suspect, may be I did something wrong in my codes or the Ubuntu 7.04 has an error on freeing memory. But the linux community stating that the Linux Ubuntu is very good in Memory management.. anyways I'll keep you posted on this I'll try something different.


                              Thanks and Best regards to all experts here,
                              Norman

                              Comment

                              Working...