Использование calloc в C для инициализации массива int, но без получения обнуленного буфера

Я работаю над решением проблемы практики программирования и возвращаюсь к C, чтобы освежиться. Во всяком случае, у меня есть ошибки с массивом, который я получаю через calloc. Массив, который я возвращаю, не инициализируется нулем. Вот отрывок моего кода вместе с выводом, который он производит. Я боюсь, что могу просто упустить что-то болезненно очевидное или идиосинкразическое.

int * check_digits;
    // For loop iterating over all numbers with fangsize digits
    for (int i = smallest_fang; i < largest_fang; i++) {

        char fang1_word[N];
        sprintf(fang1_word, "%d", i);

        for (int j = i; j < largest_fang; j++) {

            int dracula;
            char dracula_word[N];
            char fang2_word[N];

            check_digits = (int *) calloc((size_t) N, (size_t) sizeof(int));
            printf("HELLO\n");
            for (int arg = 0; arg < 10; arg++) {
                printf("%d\n", check_digits[arg]);
            }
            printf("\n");

            // Verify they both aren't divisible by ten.
            if (((i % 10) == 0) && ((j % 10) == 0)) { 
                free(check_digits);
                continue;   
            }


            // Calculate potential vampire
            dracula = i * j;
            printf("Here, I is %d and J is %d.\n", i, j);
            printf("The potential vampire is %d\n", dracula);

            // Verify potential vampire has enough digits
            sprintf(dracula_word, "%d", dracula);
            sprintf(fang2_word, "%d", j);

            printf("Lenth of dracula word is %ld\n", strlen(dracula_word));
            if ((int) strlen(dracula_word) != N) {
                printf("Wasn't long enough.\n");
                free(check_digits);
                continue;
            }


            // Count up all the vampire's digits into check_digits
            for (int k = 0; k < N; k++) {
                char digit_char;
                int digit;

                digit_char = dracula_word[k];
                digit = (int) strtol( (const char *) &digit_char, (char**) NULL, 10);
                printf("digit is %d\n", digit);
                check_digits[digit]++;
            }

            // Print out check digits
            printf("\nPrinting out check digits.\n");
            for (int k = 0; k < 10; k++) {
                printf("The digit %d occurs %d times.\n", k, check_digits[k]);
            }

            // See if they all match. No need to make sure any value of
            // check_digits is above zero because digits must already add
            // up.
            int failed = 0;
            for (int k = 0; k < N/2; k++) {
                char digit_char;
                int digit;

                digit_char = fang1_word[k];
                digit = (int) strtol( (const char *) &digit_char, (char**) NULL, 10);

                check_digits[digit]--;
                if (check_digits[digit] < 0) {
                    failed = 1;
                    break;
                }

                digit_char = fang2_word[k];
                digit = (int) strtol( (const char *) &digit_char, (char**) NULL, 10);

                check_digits[digit]--;
                if (check_digits[digit] < 0) {
                    failed = 1;
                    break;
                }
            }

            // Failed at some point during digit check phase
            if (failed) { 
                free(check_digits);
                continue;   
            }

            // They all seem to match. Print vampire number
            else {
                printf("Found vampire number: %d * %d = %d\n", i, j, dracula);
            }
        }

Когда я запускаю код и grep для известного ложного срабатывания, я получаю следующие строки:

240211-HELLO
240217-0
240219-0
240221-0
240223-0
240225-3
240227-5
240229-1
240231-3
240233-0
240235-2
240237-
240238-Here, I is 21 and J is 58.
240265:The potential vampire is 1218
240295-Lenth of dracula word is 4
240322-digit is 1
240333-digit is 2
240344-digit is 1
240355-digit is 8
240366-
240367-Printing out check digits.
240394-The digit 0 occurs 0 times.
240422-The digit 1 occurs 2 times.
240450-The digit 2 occurs 1 times.
240478-The digit 3 occurs 0 times.
240506-The digit 4 occurs 3 times.
240534-The digit 5 occurs 5 times.
240562-The digit 6 occurs 1 times.
240590-The digit 7 occurs 3 times.
240618-The digit 8 occurs 1 times.
240646-The digit 9 occurs 2 times.
240674:Found vampire number: 21 * 58 = 1218

По сути, сразу после того, как calloc возвращает буфер памяти, я распечатываю его и вижу, что это неясно, что позже приводит к проблемам.


person Whelchel    schedule 23.07.2013    source источник
comment
Наверное глупый вопрос: есть N == 4?   -  person Casey    schedule 23.07.2013
comment
Почему вы удивлены тем, что в check_digits всего 4 обнуленных целых числа, когда вы сказали calloc, что хотите 4 целых числа?   -  person Casey    schedule 23.07.2013
comment
Эээ... было бы неплохо... должно быть десять. Спасибо.   -  person Whelchel    schedule 23.07.2013
comment
Вам не нужно приводить возвращаемое значение malloc или calloc в программе на C.   -  person Carl Norum    schedule 23.07.2013
comment
преобразование результата sizeof() в size_t также не требуется.   -  person Casey    schedule 23.07.2013
comment
Да, раньше у меня их не было, но я добавил их, чтобы посмотреть, будет ли это иметь значение... Спасибо.   -  person Whelchel    schedule 23.07.2013


Ответы (1)


Я думаю, что ошибка здесь:

check_digits = (int *) calloc((size_t) N, (size_t) sizeof(int));
printf("HELLO\n");
for (int arg = 0; arg < 10; arg++) {
    printf("%d\n", check_digits[arg]);
}

Вы выделяете массив из N элементов (возможно, 4), но затем получаете доступ к 10 элементам в цикле for. На самом деле, первые 4 элемента правильно установлены равными нулю, поэтому calloc работает правильно. Другие значения (от 4 до 9) являются случайными значениями, поскольку они находятся вне памяти, выделенной с помощью calloc, и поэтому не обнуляются.

Чтобы решить эту проблему, вы должны использовать N в каждом цикле, где вы обращаетесь к элементам check_ degitis.

person Giuseppe Pes    schedule 23.07.2013