Thread: How to correctly free all memory please help!

  1. #1
    Registered User
    Join Date
    Jan 2012
    Posts
    166

    How to correctly free all memory please help!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #define FLUSH while (getchar() != '\n')
    
    //      Global Declarations
    typedef int KEY_TYPE;
    typedef struct
    {
      KEY_TYPE key;
      char modifier;
      char *name;
      float gpa;
    
    }   DATA;
    typedef struct nodeTag
    {
      DATA            data;
      struct nodeTag* link;
    } NODE;
    
    //      Function Declarations
    NODE* insertNode (NODE*  pList, NODE*  pPre, DATA  item);
    bool  searchList (NODE*  pList, NODE**   pPre,
                    NODE** pCur,  DATA* item);
    
    void  printList  (NODE*  pList);
    NODE* buildList  (char*  fileID);
    bool  getData    (FILE*  fpData, DATA* pData);
    
    void printListByGpa (NODE* pList, float target);
    void saveHiGpa (NODE* pList);
    
    float HIGPA = 0.0;
    //      Header file to include functions (Not in text)
    //#include "P15-LIST.H"
    
    int main (void)
    {
    //      Local Declarations
          NODE*  pList;
          NODE*  pPre;
          NODE*  pCur;
          DATA   data;
          double avrg;
          char   more;
    
    //      Statements
          printf("Begin list test driver\n\n");
    
          //      Build List
          pList = buildList("gpaDS.txt");
    
          if (!pList)
          {
              printf("Error building chron file\a\n");
              exit  (100);
          }
          printList (pList);
          saveHiGpa (pList);
    
          while(1)
          {
    
           printf("\nPrint by gpa tests.\n");
    
           printf("Enter target score:            ");
           while (scanf ("%f", &data.gpa) != 1)
           {
                   FLUSH;
                   printf("Invalid number, please re-enter:        ");
           }
           if(data.gpa==-1){
              printf("Exiting...\n");
              break;
           }
    
           printListByGpa (pList, data.gpa);
    
          }
    
          printf("\nTests complete.\n");
          return 0;
    } // main
    
    /*      ==================== insertNode ====================
          This function inserts a single node into a linear list.
             Pre   pList is pointer to the list; may be null
                   pPre points to new node.s predecessor
                   item contains data to be inserted
             Post  returns the head pointer
    */
    NODE* insertNode (NODE* pList, NODE* pPre, DATA item)
    {
    //      Local Declarations
          NODE* pNew;
    
    //      Statements
          if (!(pNew  = (NODE*)malloc(sizeof(NODE))))
              printf("\aMemory overflow in insert\n"), exit (100);
    
          pNew->data = item;
          if (pPre == NULL)
      {
              // Inserting before first node or to empty list
              pNew->link  = pList;
              pList       = pNew;
          } // if pPre
          else
          {
              // Inserting in middle or at end
              pNew->link = pPre->link;
              pPre->link = pNew;
          } // else
          return pList;
    }       // insertNode
    
    /*      ==================== searchList ====================
          Given key value, finds the location of a node
             Pre   pList points to a head node
                   pPre points to variable to receive pred
                   pCur points to variable for current node
                   target is a pointer to the data with key being sought
             Post  pCur points to first node with >= key
                   -or- null if target > key of last node
                   pPre points to largest node < than key
                   -or- null if target < key of first node
                   function returns true if found
                                    false if not found
    */
    bool searchList (NODE*  pList, NODE**   pPre,
                   NODE** pCur,  DATA* target)
    {
    //      Local Declarations
          bool found = false;
    
    //      Statements
          *pPre = NULL;
          *pCur = pList;
    
          // start the search from beginning
          while (*pCur != NULL && target->key > (*pCur)->data.key )
          {
              *pPre = *pCur;
              *pCur = (*pCur)->link;
          } // while
    
          while (*pCur != NULL && target->key == (*pCur)->data.key && target->modifier>(*pCur)->data.modifier)
           {
    
              *pPre = *pCur;
              *pCur = (*pCur)->link;
           }
    
          if (*pCur != NULL && target->key == (*pCur)->data.key && target->modifier==(*pCur)->data.modifier)
             found = true;
    
          return found;
    
    }       // searchList
    
    
    /*      Traverse and print a linear list.
             Pre   pList is a valid linear list
             Post  List has been printed
    */
    void printList (NODE* pList)
    {
    //      Local Declarations
          NODE* pWalker;
    
    //      Statements
          pWalker = pList;
          printf("List contains:\n");
            printf(" PIN   Name       GPA\n");
            printf(" === ============ =======   \n");
           while (pWalker)
          {             printf("%3d%c %s %.1f\n",
                 pWalker->data.key,pWalker->data.modifier,pWalker->data.name,pWalker->data.gpa);
              pWalker = pWalker->link;
          } // while
          printf("\n");
          return;
    } // printList
    
    
    /*      Traverse and print a linear list.
             Pre   pList is a valid linear list
             Post  List has been printed
    */
    void saveHiGpa (NODE* pList)
    {
    //      Local Declarations
          NODE* pWalker;
          char* best_students_file="best_students.txt";
          FILE* foutData;
    
    //      Statements
          pWalker = pList;
    
    
          foutData=fopen(best_students_file,"w");
          if(!foutData){
              printf("Error opening file %s\a\n", best_students_file);
              exit (210);
          }
    
          while (pWalker)
          {
              if(pWalker->data.gpa==HIGPA){
                   fprintf(foutData,"%3d%c %s %.1f\n",
                      pWalker->data.key,pWalker->data.modifier,pWalker->data.name,pWalker->data.gpa);
              }
              pWalker = pWalker->link;
          } // while
          fclose(foutData);
          return;
    } // printList
    
    
    
    /*      Traverse and print a linear list.
             Pre   pList is a valid linear list
             Post  List has been printed
    */
    void printListByGpa (NODE* pList, float target)
    {
    //      Local Declarations
          NODE* pWalker;
    
    //      Statements
          pWalker = pList;
          printf("List contains:\n");
    
          while (pWalker)
          {
              if(pWalker->data.gpa>=target){
                   printf("%3d%c %s %.1f\n",
                      pWalker->data.key,pWalker->data.modifier,pWalker->data.name,pWalker->data.gpa);
              }
              pWalker = pWalker->link;
          } // while
          printf("\n");
          return;
    } // printList
    
    /*      ==================== buildList ====================
          This program builds a key-sequenced linear list.
             Pre   fileID is file that contains data for list
             Post  list built
                   returns pointer to head of list
    */
    NODE* buildList (char* fileID)
    {
    //      Local Declarations
          DATA  data;
          NODE* pList;
          NODE* pPre;
          NODE* pCur;
          FILE* fpData;
    
    //      Statements
          pList = NULL;
    
          fpData = fopen(fileID, "r");
          if (!fpData)
          {
              printf("Error opening file %s\a\n", fileID);
              exit (210);
          } // if open fail
    
          while (getData (fpData, &data))
          {
              if(HIGPA==0.0){
                  HIGPA=data.gpa;
              } else {
                  if(HIGPA<data.gpa){
                     HIGPA=data.gpa;
                  }
              }
    
    
              // Determine insert position
              searchList (pList, &pPre, &pCur, &data);
              pList = insertNode(pList, pPre, data);
          } // while
          return pList;
    } // buildList
    
    /*      ==================== getData ====================
          Reads data from file.
             Pre   fpData is an open file
                   pData is pointer to input structure
             Post  data read
               returns success/failure
    */
    
    bool getData (FILE* fpData, DATA* pData)
    {
    //      Local Definitions
          char *ioResult;
          char buffer[100];
           pData->name = (char*) malloc(100*sizeof(char));
    //      Statements
    
          ioResult = fgets(buffer, 100, fpData);
          if(ioResult){
             sscanf(buffer, "%d%c %[^;]%*c %f", &(pData->key), &(pData->modifier), pData->name, &(pData->gpa));
          }
          return ioResult;
    }       // getData
    void destroyList(NODE* pList, DATA data)
    {
    free(pList);
    
    return;
    }
    -I'm pretty bad at managing to correctly free up all memory. Could someone please help me out? I freed pList, but I'm not sure what else I need to free up and how. I use valgrind to check for memory leaks, and it seems like I still have quite a lot. Thank you for your time!

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    One way to clean up a list is to create a remove node function and then design a loop to call it on the entire list.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    First things first. At 151 posts, I'm sure we've covered this with you before, but just in case: make sure your code is properly indented and that you copy-paste it as plain text. That allows the forum's syntax highlighter to properly highlight the code, also improving readability. Preview or review your post, and if it doesn't look perfect, edit it immediately. You will get better help this way, and less complaints. You have now been warned, no more excuses.

    Another quick note, avoid useless comments. In particular, I'm looking at all your comments that say "Local Definitions", "Statements", and most of the ones that you use to comment the end of a conditional, loop, function, etc. What precisely is "ended" with a closing curly brace should be clear from the indentation. Commenting the end of a block, IMO, is only really useful if you have complex code with a large block that doesn't fit on one screen, and it's not obvious otherwise.

    Also, it would help us debug your program if you provided a sample data file and/or posted the results of running valgrind.

    Now, onto your issue:
    It's not that hard to free the memory you use. For every malloc/calloc/realloc call you have, you should have a corresponding call to free. You should always free the "inner-most" memory first. If you free the "outer" memory first, you lose access to the inner memory and can't free it. In your code, you have two malloc calls. One is to malloc a NODE, the other is to malloc the name field of a DATA struct (which is ultimately inside a NODE). That means you should free the name element first, then free the NODE it belonged to. You must free pList->data.name before you free the pList in destroyList.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How does free() know how much memory it has to free?
    By shiroaisu in forum C Programming
    Replies: 14
    Last Post: 09-09-2011, 11:28 AM
  2. free RAM memory
    By koyboy in forum C++ Programming
    Replies: 1
    Last Post: 05-11-2008, 07:03 AM
  3. How must I correctly allocate memory?
    By JFonseka in forum C Programming
    Replies: 3
    Last Post: 10-25-2007, 03:31 AM
  4. How to free memory ?
    By Brw_Abhi in forum C++ Programming
    Replies: 8
    Last Post: 06-05-2007, 01:19 AM
  5. free memory
    By anthonye in forum C++ Programming
    Replies: 1
    Last Post: 04-12-2002, 05:39 AM