Thread: Function to check memory left from malloc and free?

  1. #1
    Registered User
    Join Date
    Apr 2006
    Posts
    16

    Function to check memory left from malloc and free?

    I just started learning malloc and free, but I'm not sure if I'm using them right. Is there a way to check how much memory is left after a free? I seem to be using up all the heap space pretty quickly in a test program.
    Last edited by Lechx; 04-24-2006 at 12:54 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > Is there a way to check how much memory is left after a free?
    From within the program, or using some kind of "process monitor" ?
    Either way, you need to say what you're using if you want a specific answer.

    > I seem to be using up all the heap space pretty quickly in a test program.
    Post your test program for further comments.

    Typically, when you ask for lots of memory the program goes and gets a large block from the OS and then gives it to you as required. But when you free it, it doesn't automatically return to the OS.
    So if you're just using a process monitor, you may see the amount of memory go up, but not down.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2005
    Posts
    167
    i use valgrind to check my memory leaks

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    16
    i would like to check the memory that my program is using through a function. I've attached my code below.

    I've never used a debugger, but i'll take a look at valgrind.

    Code:
    /*This hash table resizes the table once the size exceeds # of buckets */
    
    #include <stdio.h>
    
    #define	INITNUMBUCKETS		5
    #define	LINKBLOCKSIZE		16
    #define RESIZERATIO		1
    #define NOMATCH			-1
    #define DEBUG			1
    
    typedef struct	Link {
       int		Key;
       int		Value;
       struct Link	*Next;
    } Link;
    
    typedef struct	{
       Link		**Buckets;
       int		NumBuckets;
       Link		*FreeLinks;
       int		Size;
    } HashTable;
    
    int main(int argc, char *argv[]) {
       HashTable	HT;
       FILE		*FP;
       int		NumVals, Key, Value;
       void		Initialize_Hash_Table(HashTable *HT);
       void		Insert(HashTable *HT, int Key, int Value);
       int		Lookup(HashTable *HT, int Key);
       void		Remove(HashTable *HT, int Key);
       void		Print_Hash_Table(HashTable *HT);
    
       if (argc != 2) {
         printf("usage: %s valuefile\n", argv[0]);
         exit(1);
       }
       FP = fopen(argv[1], "r");
       if (FP == NULL) {
          printf("%s could not be opened; check the filename\n", argv[1]);
          exit(1);
       } else {
          Initialize_Hash_Table(&HT);
          do {
             NumVals = fscanf(FP, "%d %d\n", &Key, &Value);
             if (NumVals == 2) {
                if (Key < 0) {
                   printf("Remove(%d)\n", -Key);
                   Remove(&HT, -Key);
                } else if (Value == -1) {
                   Value = Lookup(&HT, Key);
                   printf("%d = Lookup(%d)\n", Value, Key);
                } else {
                   printf("Insert(%d, %d)\n", Key, Value);
                   Insert(&HT, Key, Value);
                }
                if (DEBUG)
                   Print_Hash_Table(&HT);
             }
          } while (NumVals == 2);
          Print_Hash_Table(&HT);
          fclose(FP);
          exit(0);
       }
    }
    
    /* Hash: This routine transforms the key into a bucket number. */
    
    int Hash(HashTable *HT, int Key) {
       return Key % HT->NumBuckets;
    }
    
    /* Initialize Hash Table: This routine initializes a new hash table
    object. Buckets are allocated and cleared; the Freelist is
    initialized, and the size is zeroed. */
    
    void Initialize_Hash_Table(HashTable *HT) {
       int		Index;
       void		*malloc(unsigned int);
    
       HT->NumBuckets = INITNUMBUCKETS;
       HT->Buckets = (Link **) malloc(HT->NumBuckets * sizeof(Link *));
       if (HT->Buckets == NULL) {
          printf("Out of heap memory\n");
          exit(1);
       }
       for (Index = 0; Index < HT->NumBuckets; Index++)
          HT->Buckets[Index] = NULL;
       HT->FreeLinks = NULL;
       HT->Size = 0;
    }
    
    /* Make New Links: This routine allocates, initializes, and returns a
    new block of link objects. */
    
    Link *Make_New_Links() {
       Link		*NewLinks;
       int		Index;
       void		*malloc(unsigned int);
       void		Print_Next_Link(Link *Next);
    
       if (DEBUG)
          printf("   making more links\n");
       NewLinks = (Link *) malloc(LINKBLOCKSIZE * sizeof(Link));
       if (NewLinks == NULL) {
          printf("Out of heap memory\n");
          exit(1);
       }
       for (Index = 0; Index < LINKBLOCKSIZE; Index++) {
          NewLinks[Index].Key = -1;
          NewLinks[Index].Value = -1;
          if (Index == LINKBLOCKSIZE - 1)
             NewLinks[Index].Next = NULL;
          else
             NewLinks[Index].Next = &(NewLinks[Index + 1]);
       }
       if (DEBUG) {
          printf("   free list\n");
          Print_Next_Link(NewLinks);
       }
       return NewLinks;
    }
    
    /* Print Hash Table: This routine prints the size and contents of a
    hash table object. */
    
    void Print_Hash_Table(HashTable *HT) {
        int		Index;
        void	Print_Next_Link(Link *Next);
    
        if (DEBUG)
           printf("   [HashTable %u, size = %d]\n", HT, HT->Size);
        else
           printf("   [HashTable size = %d]\n", HT->Size);
        for (Index = 0; Index < HT->NumBuckets; Index++) {
           if (DEBUG)
              printf("   bucket %d\n", Index);
           Print_Next_Link(HT->Buckets[Index]);
        }
    }
    
    /* Print Next Link: This recursive routine prints the next non-NULL
    link entry including its key and value. */
    
    void Print_Next_Link(Link *NextLink) {
       if (NextLink != NULL) {
          if (DEBUG)
             printf("      <%u: %5d, %3d, %u>\n", NextLink, NextLink->Key, NextLink->Value, NextLink->Next);
          else
             printf("      <%5d:%5d>\n", NextLink->Key, NextLink->Value);
          Print_Next_Link(NextLink->Next);
       }
    }
    
    /* Insert: This routine inserts a key value pair in the hash table.
    If the key already exists, the value is updated. Otherwise a new link
    is allocated, initlized, and added to the appropriate bucket list. */
    
    void Insert(HashTable *HT, int Key, int Value) {
       Link		*FoundLink;
       Link		*Find_Key(HashTable *HT, int Key);
       Link		*Make_New_Links();
       int		Hash(HashTable *HT, int Key);
       void		Resize_Hash_Table(HashTable *HT);
     
       FoundLink = Find_Key(HT, Key);
       if (FoundLink == NULL) {
          if (HT->FreeLinks == NULL)
             HT->FreeLinks = Make_New_Links();
          FoundLink = HT->FreeLinks;
          HT->FreeLinks = HT->FreeLinks->Next;
          FoundLink->Key = Key;
          FoundLink->Value = Value;
          FoundLink->Next = HT->Buckets[Hash(HT, Key)];
          HT->Buckets[Hash(HT, Key)] = FoundLink;
          HT->Size += 1;
          if (HT->Size > HT->NumBuckets * RESIZERATIO)
             Resize_Hash_Table(HT);
       } else
          FoundLink->Value = Value;
    }
    
    /* Lookup: This routine attempts to locate a key in the hash table. If
    the key is located, the value is returned, otherwise NOMATCH is
    returned. A interal function performs the search returning the
    matching link if the key si found or NULL if it is not found. */
    
    int Lookup(HashTable *HT, int Key) {
       Link		*FoundLink;
       Link		*Find_Key(HashTable *HT, int Key);
    
       FoundLink = Find_Key(HT, Key);
       if (FoundLink == NULL)
          return -1;
       else
          return FoundLink->Value;
    }
    
    /* Remove: This routine removes a key value pair from the hash table.
    It pushes the removed link back on the FreeLinks list for later reuse. */
    
    void Remove(HashTable *HT, int Key) {
       int		Index;
       Link		*ThisLink;
       Link		**TrailingPointer;
       int		Hash(HashTable *HT, int Key);
       void		Print_Next_Link(Link *Next);
    
       Index = Hash(HT, Key);
       ThisLink = HT->Buckets[Index];
       TrailingPointer = &(HT->Buckets[Index]);
       while(ThisLink != NULL && ThisLink->Key != Key) {
          TrailingPointer = &(ThisLink->Next);
          ThisLink = ThisLink->Next;   
       }
       if (ThisLink != NULL) {
          *TrailingPointer = ThisLink->Next;
          ThisLink->Next = HT->FreeLinks;
          HT->FreeLinks = ThisLink;
          HT->Size -= 1;
          if (DEBUG) {
             printf("   free list\n");
             Print_Next_Link(HT->FreeLinks);
          }
       }
    }
    
    /* Find_Key: This internal routine performs a hash table lookup,
    returning the located link is the key exists in the hash table, or
    NULL if it does not. */
    
    Link *Find_Key(HashTable *HT, int Key) {
       Link		*ThisLink;
       int		Index;
       int		Hash(HashTable *HT, int Key);
    
       Index = Hash(HT, Key);
       ThisLink = HT->Buckets[Index];
       while(ThisLink != NULL && ThisLink->Key != Key)
          ThisLink = ThisLink->Next;   
       return ThisLink;
    }
    
    
    
    void Resize_Hash_Table(HashTable *HT){
         //Initialize new HT     
            //printf("DOING THE RESIZE HASH TABLE \n"); /////////////////////REMOVE
         
       int		Index;
       void		*malloc(unsigned int);
       HashTable	HT2;
       int ind, num;
       Link *current=NULL, *temp=NULL;
       void insertCustom(HashTable *HT, int Key, int Value);
       void Custom_Print_Hash_Table(HashTable *HT);
       
       
       
        HT2.NumBuckets = 2*(HT->NumBuckets)+1;
       HT2.Buckets = (Link **) malloc(HT->NumBuckets * sizeof(Link *));
       if (HT2.Buckets == NULL) {
          printf("Out of heap memory\n");
          exit(1);
       }
       for (Index = 0; Index < HT2.NumBuckets; Index++)
          HT2.Buckets[Index] = NULL;
       HT2.FreeLinks = NULL;
       HT2.Size = 0;
       
       //end Initialize new HT
    
       
       //Begin copy old contents to new contents
       ind=1;
       num=0;
       while(num<HT->NumBuckets){
           current=HT->Buckets[num];
           if(current==NULL){
                num++; //If the rest of the bucket is empty, goto next bucket
           }
           else{ 
                while(current!=NULL){//Else, iterate through the bucket and insert
                     insertCustom(&HT2, current->Key, current->Value);
    
                     temp=current->Next;
                     free(current);
    
                     current=temp; //Next item in the bucket
                     
                }
                num++;
                
           }
                           
       ind++;                
       }
    
         *HT=HT2;
         
         
         }
         
    void insertCustom(HashTable *HT, int Key, int Value) { 
              HT->Size =HT->Size + 1;
              if(HT->FreeLinks==0){ //If no free links
                  Link *Make_New_Links();
                  Link *freed=Make_New_Links();
                  HT->FreeLinks=freed->Next;
                  freed->Key=Key;
                  freed->Value=Value;
                  freed->Next=HT->Buckets[Hash(HT, Key)];
                  HT->Buckets[Hash(HT, Key)]=freed;
              }
              else{ //If free links exist
                   Link *current=HT->FreeLinks;
                   current->Key=Key;
                   current->Value=Value;
                   HT->FreeLinks=current->Next;                      
                   current->Next=HT->Buckets[Hash(HT, Key)];     
                   HT->Buckets[Hash(HT, Key)]=current;
              } 
                  
             
    }
      
    
    void Custom_Print_Hash_Table(HashTable *HT) { /////////////////////REMOVE
        int		Index;
        void	Print_Next_Link(Link *Next);
    
           printf("   [HashTable %u, size = %d]\n", HT, HT->Size);
    
        for (Index = 0; Index < HT->NumBuckets; Index++) {
    
              printf("   bucket %d\n", Index);
           Print_Next_Link(HT->Buckets[Index]);
        }
    }
    Last edited by Lechx; 04-23-2006 at 04:55 PM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM
  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