Calloc does not initialize entire memory block to zero

While playing with the implementation of a hashmap toy example (for fun) I've found a strange behaviour, calloc does not initialize the entire memory block I want to zero, as supposed to do. The following code should produce no output if the entire memory block is zeroed:

#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();


}

However it produces the output:

item 25, key_null 1, value_null 0

The only non-zero item is always the one at DICT_INITIAL_CAPACITY / 2. I've tried also using memset to put all the block to zero and the result is the same. If I put the memory to zero explicitly using:

for (int j = 0; j < my_dict->max_capacity; j++){
            (my_dict->items + j)->ptr_key = 0;
            (my_dict->items + j)->ptr_value = 0;
        }

Then I get the desired behavior. But I do not understand why it does not work using calloc. What am I doing wrong?


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

Should be

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

Also note that, in general, calloc may not set pointers to null (although it does on all modern systems that I know of). It would be safer to explicitly initialize any pointers that are meant to be null.

Having said that, you seem to be storing a size variable to indicate the size of the dictionary, so you could avoid this problem entirely by not reading entries beyond the current size ; and when you do increase size then initialize the entries you have just added.

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

上一篇: 堆结构中字符指针字段的malloc / calloc上的堆损坏

下一篇: Calloc不会将整个内存块初始化为零