Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Calloc不会将整个内存块初始化为零_C_Calloc - Fatal编程技术网

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

在玩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();


}
唯一的非零项始终是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);