Calloc不会将整个内存块初始化为零
在玩hashmap玩具示例的实现时(为了好玩),我发现了一个奇怪的行为,calloc不会像预期的那样初始化我想要归零的整个内存块。如果整个内存块归零,则以下代码不应产生输出:Calloc不会将整个内存块初始化为零,c,calloc,C,Calloc,在玩hashmap玩具示例的实现时(为了好玩),我发现了一个奇怪的行为,calloc不会像预期的那样初始化我想要归零的整个内存块。如果整个内存块归零,则以下代码不应产生输出: #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #define DICT_INITIAL_CAPACITY 50 typedef struct dictiona
#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();
}
唯一的非零项始终是DICT_初始容量/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;
}
for(int j=0;jmax_capacity;j++){
(my_dict->items+j)->ptr_key=0;
(my_dict->items+j)->ptr_值=0;
}
然后我得到想要的行为。但我不明白为什么使用calloc时它不起作用。我做错了什么
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof my_dict->items);
应该是
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof *my_dict->items);
还要注意的是,一般来说,calloc
可能不会将指针设置为null(尽管我所知道的所有现代系统上都是这样)。显式初始化任何要为null的指针会更安全
话虽如此,您似乎正在存储一个
size
变量来指示字典的大小,因此您可以通过不读取当前size
之外的条目来完全避免此问题;当您确实增加大小时,请初始化刚才添加的条目。考虑使用x[y]。z
而不是(x+y)->z
,前者更容易捕获,Matt。这表明我相信,由于sizeof
始终是静态计算的(由编译器),因此应该始终将sizeof
与类型名一起使用,而不是与变量名一起使用。
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof *my_dict->items);