【发布时间】:2012-11-20 08:49:24
【问题描述】:
所以我遇到了一个问题,我有一个 char*s(声明为)char** 数组,其中该数组是动态分配的(通过 calloc),但其中的 char*s 是静态的。
这对我来说很好,直到我尝试释放数组(在调整大小期间),此时我得到
*** glibc detected *** ./hash_table_test: free(): invalid next size (normal): 0x0891f028 ***
我尝试将数组中的所有 ptrs 设置为 NULL,但随后出现错误
*** glibc detected *** ./hash_table_test: double free or corruption (!prev): 0x0815b028 ***
以下是相关代码:
表结构:
struct string_hash_table {
//Array of c-strings
char** table;
//number of elements in the table
int num_elements;
//size of table
int table_size;
//Primes
int *primes;
//Current position in primes array
int primes_index;
//the size of the primes array
int primes_size;
};
//TypeDefs--------------------------------
typedef struct string_hash_table HashTable;
Rehash 函数(错误来源)
void rehash_string(HashTable *table) {
int prev_size = table->table_size;
int i;
table->table_size = table->table_size * 2;
//create new array
char** new_table = calloc(table->table_size, sizeof(char*));
printf("new table created\n");
int index;
printf("before loop prev_size is %d\n", prev_size);
//add all elements to new_table
for (i = 0; i < prev_size; i++) {
printf("on %d\n", i);
index = find_spot_string(new_table, table->table_size, table->table[i]);
printf("after find_spot_string\n");
if (index != -1) {
table->table[index] = table->table[i];
}
}
//free and swap
printf("before free\n");
empty_string_array(table->table, table->table_size);
free(table->table);
table->table = new_table;
HashTable结构的初始化:
//Takes a HashTable and initializes it
void init_hash_table(HashTable *table) {
table->primes_index = 0;
table->num_elements = 0;
table->primes_size = 297;
table->primes = prime_list;
table->table_size = table->primes[0];
table->table = calloc(table->table_size, sizeof(char*));
}
内的静态字符串声明:
char* temp = "hello";
add_hash_table_string(table, temp);
temp = "luck";
add_hash_table_string(table, temp);
temp = "stuck";
add_hash_table_string(table, temp);
temp = "buck";
add_hash_table_string(table, temp);
temp = "muck";
add_hash_table_string(table, temp);
temp = "much";
add_hash_table_string(table, temp);
目前我只是在这里测试我的代码,除了上面的重新散列函数之外,一切正常。谁有想法?或我应该遵循的线索?
编辑:为 add_hash_table_string 添加代码
void add_hash_table_string(HashTable *table, char* element) {
//if non-null element, and element is not in the HashTable
if (element != NULL && contains_hash_table_string(table, element) == 1) {
//if the table is full
if (table->table_size / 2 < table->num_elements) {
rehash_string(table);
}
int index = find_spot_string(table->table, table->table_size, element);
table->table[index] = element;
table->num_elements++;
}
}
EDIT2:
忘记准确了,错误发生在 rehash 函数中的 free(table->table) 行
【问题讨论】:
-
您正在使用函数
add_hash_table_string(),我们应该猜测它的作用以及您的代码是如何出错的?您需要提供 SSCCE (Short, Self-Contained, Correct Example) 以便人们可以提供帮助。或者你应该考虑使用valgrind。 -
只有表是动态分配的,那么
empty_string_array()应该怎么做呢? -
所以我的猜测是您的
add_hash_table_string()只是获取字符指针(第二个参数)并将其放在列表中的某个位置,然后删除此指针,这将失败,因为它们从未在堆,因为它们驻留在 const-string-pool 中。 -
@arjor empty_string_array() 只是将表中的所有 ptrs 设置为 NULL。我还没有完全弄清楚免费工作的所有细微差别。我认为它可能会有所帮助..它没有大声笑
-
@pbhd 我不释放数组中的单个元素,只是释放数组。
标签: c free cstring dynamic-arrays