Calloc不会将整个内存块初始化为零

在玩哈希贴图玩具的例子(为了好玩)时,我发现了一个奇怪的行为,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 %dn", 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。 我究竟做错了什么?


my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof my_dict->items);

应该

my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof *my_dict->items);

还要注意,一般来说, calloc可能不会将指针设置为null(尽管它在我所知的所有现代系统上都有)。 显式初始化任何意味着为空的指针会更安全。

话虽如此,您似乎正在存储一个size变量来指示字典的大小,因此您可以通过不读取超出当前size条目完全避免此问题; 当你增加size然后初始化你刚添加的条目。

链接地址: http://www.djcxy.com/p/80411.html

上一篇: Calloc does not initialize entire memory block to zero

下一篇: calloc() slower than malloc() & memset()