-1

I am getting this strange problem with my code. Malloc is returning a null pointer here.. I have 3 GB memmory on my ram and it could not allocate a few bytes. Why is it happening?? Someone please help..

Here is my code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct htree{
   unsigned char ch;
   unsigned long int freq;
   struct htree *left, *right, *parent;
   };

struct code_list{
   unsigned char ch;
   char *code;
   };



typedef struct htree node;
typedef struct code_list * dict;

dict codes;

int readfile(char *filename, long int *char_count)
{
 int types = 0;
 FILE *fp = fopen(filename,"rb");
 unsigned char byteread;
 fread(&byteread,1,1,fp);
 int count=0;
 while(!feof(fp))
 {

                 if (char_count[byteread] == 0)
                 {
                 types++;
                 }
                 char_count[byteread]++;
                 fread(&byteread,1,1,fp);

 }
 fclose(fp);
 return types-1;
}
node * genhuffnode()
{
 node *t = (node *)malloc(sizeof(struct htree));
 t -> ch = '\0';
 t -> freq = 0;
 t -> left = NULL;
 t -> right = NULL;
 t -> parent = NULL;
 return t;
}

node * genhufftree(long int *char_count, int max_index)
{
 node **stack;
 node *temp;
 stack = (node **) calloc(max_index,sizeof(node *));
 int i,j=0;
 for(i=0;i<256;i++)
 {
                   if(char_count[i]>0)
                   {
                   stack[j] = (node *)malloc(sizeof(node));
                   stack[j] -> ch = i;
                   stack[j] -> freq = char_count[i];
                   stack[j] -> left = NULL;
                   stack[j] -> right = NULL;
                   stack[j] -> parent = NULL;
                   j++;
                   }
 }

 for(i=0;i<=max_index;i++)
 for(j=i+1;j<=max_index;j++)
 if(stack[j] -> freq > stack[i] -> freq)
 {
                 temp = stack[j];
                 stack[j] = stack[i];
                 stack[i] = temp;
 }
 while(i>0)
 {
           temp = genhuffnode();
           temp -> freq = stack[i] -> freq + stack[i-1] -> freq;
           temp -> left = stack[i-1];
           temp -> right = stack[i];
           stack[i-1] -> parent = temp;
           stack[i] -> parent = temp;

           for(j=i-2;j>0;j--)
           {
                              if(temp->freq > stack[j-1]->freq)
                              stack[j+1] = stack[j];
                              else break;
           }
           stack[j] = temp;
           i--;
 }
 return stack[0];
}

void generatedict(node *root, char *s)
{
 if(root == NULL)
 return;
 char *new_code;

 static int index = 0;

 int len = strlen(s)+1;

 if(root->left == NULL && root->right == NULL)
 {

               codes[index].ch = root->ch;
               codes[index].code = (char *) malloc(len*sizeof(char));
               strcpy(codes[index].code,s);
               index++;
 }
 else
 {

               new_code = (char *)(malloc(len+1));/// this malloc is causing prob
               if(new_code == NULL)
               {
               printf("Coudnt allocate memory\n");
               getchar();
               exit(1);
               }
               else 
               {
               strcpy(new_code,s);
               new_code[len] = '\0';
               new_code[len-1] = '0';
               generatedict(root->left,new_code);
               new_code[len-1] = '1';
               generatedict(root->right,new_code);
               }
 }

 free(root);
 return;
}

void writedict(int total_entries)
{
 FILE *fp = fopen("dictionary","wb");
 fwrite(codes,sizeof(struct code_list) * total_entries, sizeof(struct code_list) *         total_entries, fp);
 fclose(fp);
}                  

main()
{

  long int char_count[256];
  int max_index;
  max_index = readfile("2.jpg",char_count);
  node *root_node;
  root_node = genhufftree(char_count, max_index);
  codes = (struct code_list *)calloc(256,sizeof(struct code_list));         
  generatedict(root_node,"");
  writedict(max_index+1);

  getchar();
}

Note : please keep any file named "2.jpg" in the same folder as the  executable
Akash
  • 89
  • 3
  • 8
  • 4
    That's way too much code. Please provide a [simpler test-case](http://sscce.org). – Oliver Charlesworth May 21 '12 at 13:56
  • @OliCharlesworth Actually there is strange problem with this code only.The malloc(marked in the code) is returning NULL,GOD knows why!! I have enough memory..Thats why I had to provide full code.. – Akash May 21 '12 at 14:25
  • Why don't you print out the size of each chunk you are about to allocate before allocating to `stderr` and see at what point it fails (and therefore possibly why). – Nim May 21 '12 at 14:27
  • @Nim Yeah, I have checked that. When the malloc fails it was asked to allocate just 2 bytes of memory!! – Akash May 21 '12 at 14:31
  • @Nim about 100 kb..does it matters?? – Akash May 21 '12 at 15:12
  • When I run it, it crashes in `free(root)` in `generatedict()` 12 levels of recursion down. It is being freed twice. – William Morris May 21 '12 at 14:33
  • How is it possible?? On my machine it is crashing on the very first call to the malloc(marked in code).. – Akash May 21 '12 at 14:35
  • 1
    The behavior described in this answer strongly suggests that the crash is due to corrupted memory. Crashing at different points in different environments is good evidence of that. This is one of the hard things to get about dynamic allocation - a bad use of `malloc()` or `free()` often won't crash at the point of use - but *sets up the program to crash at any later time*. – gcbenison May 21 '12 at 14:43
  • @Akash: that is not the first call to malloc - there are hundreds of malloc in `genhufftree` and `genhuffnode` before it. – William Morris May 21 '12 at 14:46
  • @WilliamMorris yeah..but what should I do. I dont think I am doing anything wrong..So what is the problem??? – Akash May 21 '12 at 15:07
  • I'd suggest rationalising the code, simplifying, extracting loops into separate functions making each function separately testable. Write some test code for each function. Also add some comments to describe what you intend each function to do - they will help both you and the reader. And if possible, reduce the number of dynamic allocations. – William Morris May 21 '12 at 15:35
  • Hang on...91 views on a C question, and no one has commented that the OP [shouldn't cast the return from malloc()](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)? Am I on Bizarro-World SO? ;) – JoeFish May 21 '12 at 20:12

2 Answers2

3

My guess is that your program corrupts malloc pool in one of those earlier places where you call malloc (there are many malloc calls!). You are not checking the return value for most of the malloc calls.

I would suggest to check return value of malloc at all places to see which one fails first. Also, check for memory leaks in your code using valgrind (Linux) or purify (windows).

P.P
  • 117,907
  • 20
  • 175
  • 238
  • Hey, thanks for the reply. My code was crashing. So I started checking for malloc's and I found this one. I could think of no reason why it should fail. And if previous malloc's are failing then code should have crashed. And how can one corrupt malloc pools? – Akash May 21 '12 at 14:22
  • @Akash Not necessarily it should crash if previous mallocs failed. In that case, that could corrupt malloc pool structures. So check all mallocs and also make sure you "free" them correctly. – P.P May 21 '12 at 14:24
  • I have checked. There is no problem with other mallocs.. – Akash May 21 '12 at 14:49
  • No memory leaks as well? It's hard to tell exactly the lies with this kind of failure. So only way is to debug further with gdb & valgrind. – P.P May 21 '12 at 14:54
  • I am working on windows 7 and have no experience of debuggers..I just want to get my work done..Is there any simpler way of doing this?? – Akash May 21 '12 at 15:01
  • Debuggers are a part of programmers life. Take this as an opportunity to learn a debugging tool. There's no simple way I'm afraid, unless you are willing to hire someone to do the work ;) – P.P May 21 '12 at 15:06
1

If you don't think your program is exhausting memory, then most likely malloc() just thinks you've exhausted memory. This could happen if you free unallocated pointers, free the same pointer more than once, overwrite a buffer, etc. Debug your program carefully, looking for these problems, and/or use valgrind to find them automatically.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
  • Hey, thanks for the reply. I dont think i am doing something wrong with "free". It could be because of overwritten buffer. I'll check for that.. – Akash May 21 '12 at 14:23