Reputation: 582
I am trying to implement a hash table in c. So i initialize my table like this:
int size = 4;
float filled_values = 0;
struct block{
short int empty;
int value;
};
void initialize(struct block **table){
int i;
free(*table);
*table = malloc(size * sizeof(struct block));
for(i = 0; i < size; i++) (*table)[i].empty = 0;
return;
}
int main(){
struct block *table;
table = NULL;
initialize(&table);
}
everything works fine with insertions too.
void insert_utility(int value, struct block **table){
int index = hash(value);
int i = index;
for(;; i = (i + 1) % size){
if ((*table)[i].empty == 0){
(*table)[i].value = value;
(*table)[i].empty = 1;
return;
}
}
}
void insert(int value, struct block **table){
insert_utility(value, table);
int i;
filled_values++;
if (filled_values / (float)size >= 0.5) double_table(table);
return;
}
However when the table gets half full, I double the tables size to ensure reliablity.
void double_table(struct block **table){
int i;
int old_size = size;
size *= 2;
struct block **table_2;
*table_2 = malloc(size * sizeof(struct block) * 2);
for(i = 0; i < size; i++) (*table_2)[i].empty = 0;
for(i = 0; i < old_size; i++){
if ((*table)[i].empty == 1){
insert_utility((*table)[i].value, table_2);
}
}
free(*table);
table = table_2;
}
I debugged the code to know where the error gets a block with the value empty
of neither 0 or 1.
It turns out that after I assign table = table_2;
and check the values at table
everything is fine.
Whereas after double_table
exits in the insert function, I recheck the values of empty
and value
at each block, I get different results with non-sense pointer-like big values. How could've the values been altered in that way?
Upvotes: 0
Views: 33
Reputation: 25286
You need to understand that you are working in your function on a new table, your table_2
, and when you are done, you must pass it back to the caller, the **table
parameter. Applying my comments gives the following function:
void double_table(struct block **table)
{
int i;
int old_size = size;
struct block *table_2; // this is the new table that you are working on. Just one * is enough
size *= 2;
table_2 = malloc(size * sizeof(struct block) * 2);
for(i = 0; i < size; i++) table_2[i].empty = 0;
for(i = 0; i < old_size; i++){
if ((*table)[i].empty == 1){
insert_utility((*table)[i].value, &table_2);
}
}
free(*table); // this is correct, now do that too in the following statement
*table = table_2; // dereference the caller's parameter so you assign to his variable.
}
Upvotes: 1