Ошибка выполнения при попытке создать двумерный массив с помощью typedef

#arrays #c

#массивы #c

Вопрос:

Я получаю следующую ошибку из своего кода:

 warning: incompatible pointer to integer conversion initializing 'int' with an expression of type 'void *' [-Wint-conversion]
int checkeredArray = malloc(floor(((N * N)   1)/2) * sizeof(int));

warning: incompatible integer to pointer conversion returning 'int' from a function with result type 'NEWTYPE' (aka 'int *'); take the address with amp; [-Wint-conversion]
return checkeredArray;
  

Мой код приведен ниже. Что я сделал не так?

 #include <math.h>
#include <stdlib.h>

typedef int* NEWTYPE;

NEWTYPE ARRAY(int N);

int STORE(NEWTYPE as, int N, int row, int col, int val);

int FETCH(NEWTYPE as, int N, int row, int col);


NEWTYPE ARRAY(int N)
{
    int checkeredArray = malloc(floor(((N * N)   1)/2) * sizeof(int));
    //    if (checkeredArray == NULL)
    //    {
    //        printf("Malloc failed!n");
    //        return -1;
    //    }
    return checkeredArray;
}


int STORE(NEWTYPE as, int N, int row, int col, int val)
{
    int temp;

    if ((row amp; 1) != (col amp; 1))
    {
        return -1;
    }
    else if (row < 0 || col < 0)
    {
        return -1;
    }
    else if (row >= N || col >= N)
    {
        return -1;
    }
    else {
        temp = ((N * row)/2)   (col/2);
        as = as   temp;
        *as = val;

        return 1;
    }
}

int FETCH(NEWTYPE as, int N, int row, int col)
{
    if ((row amp; 1) != (col amp; 1))
    {
        return -1;
    }
    else if (row < 0 || col < 0)
    {
        return -1;
    }
    else if (row >= N || col >= N)
    {
        return -1;
    }
    else {
        int temp = ((N * row) / 2)   (col / 2);

        as = as   temp;

        int val = *as;

        return val;
    }

}

  

Комментарии:

1. Посмотрите на это объявление int checkeredArray = malloc(floor(((N * N) 1)/2) * sizeof(int)); и перечитайте сообщение компилятора. После этого скажите, что неясно с сообщением.

2. @VladfromMoscow Это потому, что я должен объявлять checkeredArray как «NEWTYPE», а не «int»

3. @Dobby Скрывать тип указателя с помощью этого typedef: typedef int* NEWTYPE; обычно плохая идея, поскольку обычно это вызывает только путаницу.

4. int checkeredArray = malloc(floor(((N * N) 1) / 2) * sizeof(int)); -> NEWTYPE checkeredArray = malloc(floor(((N * N) 1) / 2) * sizeof(int)); . Однако могут быть и другие проблемы, я не проверял.

5. и они говорят вам определить это таким образом. Арифметика указателей — это функция, которая предоставляется только несколькими языками (и по какой-то причине не предоставляется огромным количеством других). Хотя это дает большой контроль и гибкость, это также требует большой заботы о правильном использовании и потенциальной опасности написания кода, который компилируется, но не работает. Следовательно, стало хорошим стилем не скрывать указатели, чтобы программист приложения был предупрежден при их использовании. Кто бы ни дал вам этот код, ИМХО, не учитывал требования к сопровождаемости программного обеспечения, которые важны для реального программирования.

Ответ №1:

По крайней мере

неправильное объявление типа

int checkeredArray должен быть указатель, а не an int .

 typedef int* NEWTYPE;
NEWTYPE ARRAY(int N) {
    // int checkeredArray = malloc(floor(((N * N)   1)/2) * sizeof(int));
    NEWTYPE checkeredArray = malloc(floor(((N * N)   1)/2) * sizeof(int));
    return checkeredArray;
}
  

или измените NEWTYPE на int

 typedef int NEWTYPE;
NEWTYPE *ARRAY(int N) {
    // int checkeredArray = malloc(floor(((N * N)   1)/2) * sizeof(int));
    NEWTYPE *checkeredArray = malloc(floor(((N * N)   1)/2) * sizeof(int));
    return checkeredArray;
}
  

Функция с плавающей запятой floor() не требуется

Целочисленные математические деления усекаются до 0, отбрасывая дробь.

     // NEWTYPE checkeredArray = malloc(floor(((N * N)   1)/2) * sizeof(int));
    NEWTYPE checkeredArray = malloc( ((N * N)   1)/2) * sizeof(int));
  

Также

Выделите размер ссылочного объекта, а не тип.

Проще правильно кодировать, просматривать и поддерживать.
Обратите внимание, что тип указателя checkeredArray здесь не важен — просто это указатель.

     // checkeredArray = malloc( ((N * N)   1)/2) * sizeof(int));
    checkeredArray = malloc(sizeof (*checkeredArray) * ((N * N)   1)/2));
  

int против. size_t

Когда int N он большой, N * N может переполниться, тогда как с size_t математикой это менее вероятно.

     // ((N * N)   1)/2)
    (((size_t) N * N)   1)/2)
  

или измените подпись.

 // NEWTYPE ARRAY(int N)
NEWTYPE ARRAY(size_t N)