0

I have a program to dynamically increase the capacity of a hashtable when the size of any
of its buckets goes beyond a maximum value. However i am being hit with a "* glibc
detected *
realloc(): " error when i try to run my code.

Could anyone help me out with it? Sorry for positing so much code here,but i really need
the help.

  /* structure for the hashtable containing an array of nodes */

  typedef struct Hashtable hashtable;
  struct Hashtable {
  struct node **list;
  };   


  /* the function which resizes the hashtable and re-arranges the values according to 
     new capacity */

  void reSize(hashtable *h)
   {

    int i;
    node **newlist=realloc(h->list,2*capacity*sizeof(node*));
    h->list=newlist;
   int temp=capacity,index;
   capacity=capacity * 2;
    for(i=temp;i<capacity;i++)
    h->list[i]=calloc(1,sizeof(node));
    }


    /* mystructure init */
    struct hashtable *mystruct_init()
    {
     int i;      
     hashtable *hashtable =calloc(1, sizeof(*hashtable));

     // loop through and allocate memory for each element in list
     hashtable->list= calloc(1,sizeof(node *));
      for (i = 0; i < 16; i++) {
       hashtable->list[i] = calloc(1, sizeof(node));
    }

   return hashtable;
    } 
   /* in my main function */  

    hashtable *h1=(hashtable *) mystruct_init();
    hashtable *h2=(hashtable *) mystruct_init();

I am getting this "* glibc detected * ./compareDocs: realloc(): " error when i try to run it. Could someone point out as to where i am going wrong in my code?? I've spend a whole night trying to debug this thing, so any help would be really nice. Sorry for posting so many lines of code..

3
  • 2
    Did you try using valgrind? Commented Feb 2, 2012 at 16:03
  • Can you show mystruct_init()? Commented Feb 2, 2012 at 16:04
  • @Binyamin Sharet: Sorry for not including it in the initial post. /* mystructure init */ struct hashtable *mystruct_init() { int i; hashtable *hashtable =calloc(1, sizeof(*hashtable)); // loop through and allocate memory for each element in list hashtable->list= calloc(1,sizeof(node *)); for (i = 0; i < 16; i++) { hashtable->list[i] = calloc(1, sizeof(node)); } return hashtable; } Commented Feb 2, 2012 at 16:07

2 Answers 2

3

What happens is that you allocate an array of length capacity. You then double capacity on the line that reads capacity=capacity * 2. And then you write of the end of the array in the for loop because the array is only half as long as you think it is.

node **newlist=realloc(h->list,capacity*sizeof(node*));//array of length capacity
h->list=newlist;
....
capacity=capacity * 2;//oops, capacity is now twice as big as the array
for(i=temp;i<capacity;i++)
    h->list[i]=calloc(1,sizeof(node));//and now we are writing off the end
}

There are quite likely other errors in your code. I can't see how the capacity variable is handled. Is it a global? Where is it initialised?

Also, the code you added in your edit is clearly wrong.

 hashtable->list= calloc(1,sizeof(node *));
 for (i = 0; i < 16; i++) {
     hashtable->list[i] = calloc(1, sizeof(node));
 }

Here you appear to set the initial capacity of the list to 1, but then assign 16 values. Clearly the calloc should be passed 16 rather than 1.

Sign up to request clarification or add additional context in comments.

1 Comment

i tried making it node *newlist=realloc(h->list,2*capacitysizeof(node*)); The error still persists? Am i missing something here?
1

In your mystruct_init() function you've allocated only one node * for your your list:

hashtable->list= calloc(1,sizeof(node *));

And then went on to dereference elements past the end of the allocated memory:

for (i = 0; i < 16; i++) {
   hashtable->list[i] = calloc(1, sizeof(node));

Also, in your reSize() function you use the variable capacity but that does not appear to be defined anywhere. Is this your real code? And if it is, what is the value of capacity?

Edit: You should probably make the code in your init function look like this:

struct hashtable *mystruct_init()
{
    int i;      
    hashtable *hashtable =calloc(1, sizeof(*hashtable));

    // loop through and allocate memory for each element in list
    hashtable->list= calloc(capacity, sizeof(node *));
    for (i = 0; i < capacity; i++) {
       hashtable->list[i] = calloc(1, sizeof(node));
    }
    return hashtable;
}

Notice that I've used capacity in the call to calloc() and as the controlling value in the following for loop.

3 Comments

this is my real code. And i have defined capacity globally to be 16. The same program works, when i don't have to call my re-size function, i.e when the hashtable does not have to increase it size dynamically.The init code is also used.
@hektor: Whether it works or not without calling your reSize() function does not change the fact that this is undefined behaviour. It might work, it might not. And sometimes memory overruns like this can only be caught after the error has only been made. For example, the fact that you have overrun the array may only be caught the next time you call realloc() or free() because that is the next chance that the memory allocation functions have to check the validity of the allocated memory blocks. So it appears that realloc() is the problem, but really the problem is earlier in the execution.
I understand the problem. but how should i change my program? Is this OK? hashtable->list =calloc(capacity,sizeof(node*));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.