【发布时间】:2022-01-27 20:51:34
【问题描述】:
我为一个使用 C 的快速项目编写了一个轻量级字典,但出现错误:realloc(): invalid next size。我知道这意味着我的堆以某种方式损坏了,但我不确定我做错了什么,看起来我的代码非常简单。
realloc 总是第四次访问失败,即dict->num_kvs = 4时
下面是我的代码。它包括 dict 库以及使用它的函数。任何帮助将不胜感激
违规功能:
int* get_letter_frequencies(char* stream) {
Dict* dict = Dict_initialize();
for(int i = 0; i < strlen(stream); i++) {
Dict_increment_or_add_key(dict, stream[i]);
}
int* to_return = Dict_get_values_array(dict);
Dict_free();
return to_return;
}
simple_dict.c(加上结构定义)
typedef struct kv_pair {
char key;
int value;
} KV_Pair;
typedef struct dict_ {
struct kv_pair* kv_pairs;
int num_kvs;
} Dict;
Dict* Dict_initialize() {
Dict* to_return = malloc(sizeof(Dict));
to_return->num_kvs = 0;
to_return->kv_pairs = NULL;
return to_return;
}
void Dict_free(Dict* dict) {
free(dict->kv_pairs);
free(dict);
}
int Dict_add_key(Dict* dict, char key) {
dict->num_kvs++;
printf("next size: %d\n", dict->num_kvs);
dict->kv_pairs = realloc(dict->kv_pairs, dict->num_kvs * sizeof(KV_Pair));
printf("realloc passed \n");
dict->kv_pairs[dict->num_kvs].value = 1;
return 0;
}
int Dict_find_key(Dict* dict, char key){
for(int i = 0; i < dict->num_kvs; i++) {
char cur_key = dict->kv_pairs[i].key;
if(cur_key == key) {
return i;
}
}
return -1;
}
int Dict_increment_or_add_key(Dict* dict, char key) {
int key_index = Dict_find_key(dict, key);
if(key_index == -1) {
Dict_add_key(dict, key);
} else {
dict->kv_pairs[key_index].value++;
}
}
int* Dict_get_values_array (Dict* dict) {
int* to_return = malloc(dict->num_kvs * sizeof(int));
for(int i = 0; i < dict->num_kvs; i++) {
to_return[i] = dict->kv_pairs[i].value;
}
if(dict->num_kvs > 26) {
printf("more than 26 kvs: %d", dict->num_kvs);
}
return to_return;
}
【问题讨论】:
-
内存损坏的可悲之处是程序明显失败的地方几乎永远不会出现错误。
-
换句话说,为了让其他人有机会找到问题,您需要提供可以重现问题的完整最小代码。见:minimal reproducible example。也就是说,包括
main以及设置和重现问题所需的任何其他代码。 -
dict->kv_pairs[dict->num_kvs].value = 1;访问越界内存。dict->num_kvs元素的数组分配的最大有效索引为dict->num_kvs - 1。 -
我觉得自己很傻。非常感谢你们的帮助。这确实解决了问题
-
另外,我认为你犯了一个小错误,我认为 for 循环中的第二个语句需要是
*chp;,而不是chp;,因为我们正在寻找字符为 0 ,而不是地址
标签: c memory-management memory-leaks heap-memory realloc