在玩一个hashmap玩具示例的实现(为了好玩)我发现了一个奇怪的行为,calloc没有初始化我想要归零的整个内存块 . 如果整个内存块归零,则以下代码不会产生输出:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define DICT_INITIAL_CAPACITY 50
typedef struct dictionary_item {
char* ptr_key;
void* ptr_value;
} dict_item;
typedef struct dictionary {
dict_item* items;
uint16_t size, max_capacity;
} Dict;
Dict* dict_new() {
Dict *my_dict = calloc(1, sizeof *my_dict);
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof my_dict->items);
my_dict->size = 0;
my_dict->max_capacity = DICT_INITIAL_CAPACITY;
for (int j = 0; j < my_dict->max_capacity; j++) {
int key_null = 1;
int value_null = 1;
if ((my_dict->items + j)->ptr_key != NULL)
key_null = 0;
if ((my_dict->items + j)->ptr_value != NULL)
value_null = 0;
if ((my_dict->items + j)->ptr_key != NULL || (my_dict->items + j)->ptr_value != NULL)
printf("item %d, key_null %d, value_null %d\n", j, key_null, value_null);
}
return my_dict;
}
int main(int argc, char** argv) {
Dict* dict = dict_new();
}
但它会产生输出:
item 25, key_null 1, value_null 0
唯一的非零项始终是DICT_INITIAL_CAPACITY / 2中的项 . 我也尝试使用memset将所有块都置为零,结果是相同的 . 如果我使用以下内容将内存明确归零:
for (int j = 0; j < my_dict->max_capacity; j++){
(my_dict->items + j)->ptr_key = 0;
(my_dict->items + j)->ptr_value = 0;
}
然后我得到了理想的行为 . 但我不明白为什么使用calloc不起作用 . 我究竟做错了什么?
1 回答
应该
另请注意,通常,
calloc
可能不会将指针设置为null(尽管它在我所知道的所有现代系统上都有) . 显式初始化任何意味着为null的指针会更安全 .话虽如此,你似乎存储了一个
size
变量来表示字典的大小,所以你可以通过不读取当前size
之外的条目来完全避免这个问题;当你增加size
然后初始化你刚刚添加的条目 .