Почему я получаю ненужные значения, несмотря на использование calloc ()? - PullRequest
4 голосов
/ 29 сентября 2019

Я хотел бы знать, почему первые два элемента всегда отличны от нуля. Я не знаю, как больше я могу описать вопрос, но это не позволяет мне опубликовать вопрос, поэтому я пишу это. Не уверен, что это сработает.

#include <stdio.h>
#include <stdlib.h>

#define SIZE 3

void printMatrix(int **m)
{
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++)
            printf("%d ", m[i][j]);
        printf("\n");
    }
}

int main(int argc, char const *argv[])
{
    int **matrix;

    matrix = (int **) calloc(sizeof(int), SIZE);

    for (int i = 0; i < SIZE; ++i)
        matrix[i] = (int *) calloc(sizeof(int), SIZE);

    printf("%s\n", "Matrix initialized.");

    printMatrix(matrix);

    return 0;
}

Вывод:

1371548192 32653 0 
0 0 0 
0 0 0


Ответы [ 3 ]

4 голосов
/ 29 сентября 2019

Вы не выделяете достаточно памяти:

matrix = (int **) calloc(sizeof(int), SIZE);

Здесь вы пытаетесь создать массив из 3 int *, но вы выделяете пространство только для 3 int. Если в вашей системе указатель больше int, что, скорее всего, и есть, вы пишете за концом массива, когда создаете массивы для каждой строки. Запись после конца выделенной памяти вызывает неопределенное поведение .

Поскольку вы создаете массив int *, используйте его для размера каждого элемента:

matrix = calloc(sizeof(int *), SIZE);

Кроме того, не приводите возвращаемое значение malloc / realloc / calloc, так как это может маскировать ошибку, если вы забудете #include <stdlib.h>

3 голосов
/ 29 сентября 2019

Код использует calloc(sizeof(int), SIZE), но фактический тип данных в структуре равен int *, что приводит к недостаточному выделению памяти в некоторых системах (у меня размер int равен 4, а int * - 8).

Вот предложение переписать (мы поменяем параметры размера в вызове calloc на заголовок):

int main(int argc, char const *argv[]) {
    int **matrix;

    if (!(matrix = calloc(SIZE, sizeof(*matrix)))) { 
        fprintf(stderr, "calloc failed");
        return 1;
    }

    for (int i = 0; i < SIZE; ++i) {
         if (!(matrix[i] = calloc(SIZE, sizeof(*(matrix[i]))))) {
            fprintf(stderr, "calloc failed");
            return 1;
        }
    }

    printf("%s\n", "Matrix initialized.");
    printMatrix(matrix);
    return 0;
}

Здесь мы используем *matrix и *matrix[i] вместо жесткое кодирование типы int * и int соответственно. Это может помочь нам избежать ошибок и отыскать местоположения для изменения кода, если нам нужно в какой-то момент внести коррективы типа.

Мы также проверяем, что calloc успешно, проверяя, что указатель не равен NULL. Невыполнение этого требования может привести к появлению труднодоступных ошибок из-за неопределенного поведения.

Примечание Должен ли я привести результат malloc? .

2 голосов
/ 29 сентября 2019

Справочное руководство описывает calloc как:

void* calloc (size_t num, size_t size);

Таким образом, calloc сначала берет num элементов, а затем size определенного элемента

Попробуйте:

matrix = (int **) calloc(SIZE, sizeof(int *));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...