C - 释放静态字符串的动态数组



所以我遇到了一个问题,我有一个字符数组(声明为)char**,其中数组是动态分配的(通过calloc),但其中的字符*是静态的。

这对我来说很好用,直到我尝试释放数组(在调整大小期间),此时我得到

*** 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;

重新哈希函数(错误源)

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 createdn");
int index;
printf("before loop prev_size is %dn", prev_size);
//add all elements to new_table
for (i = 0; i < prev_size; i++) {
    printf("on %dn", i);
    index = find_spot_string(new_table, table->table_size, table->table[i]);
    printf("after find_spot_stringn");
    if (index != -1) {
        table->table[index] = table->table[i];
    }
}
//free and swap
printf("before freen");
empty_string_array(table->table, table->table_size);
free(table->table);
table->table = new_table;

哈希表结构的初始化:

//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++;
    }
}

编辑2:

忘了准确,错误发生在 rehash 函数中带有 free(table->table) 的行上

一个可能的问题,您用新大小释放旧表

empty_string_array(table->table, table->table_size);

另一个可能是

index = find_spot_string(new_table, table->table_size, table->table[i]);
printf("after find_spot_stringn");
if (index != -1) {
    table->table[index] = table->table[i];

如果这应该将条目复制到new_table,则不会AFAICS。当index大于prev_size时,你写在table的末尾。

最新更新