Reputation: 1025
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..
Upvotes: 0
Views: 723
Reputation: 613461
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
.
Upvotes: 3
Reputation: 6608
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.
Upvotes: 1