Доступ к массиву int, передаваемому как ошибки void указателя - PullRequest
0 голосов
/ 15 декабря 2018

Я играю с указателями и наткнулся на эту проблему.Как и в этом вопросе Я хотел подпись универсального метода для функции foo, поэтому я выбрал void * input в качестве параметра.Из соображений тестирования я поместил указатель void на указатель int **, чтобы использовать его как двумерный массив.

#include <stdio.h>
#include <stdlib.h>
void * foo(void *input, size_t mySize)
{
    for (size_t i = 0; i < mySize; ++i)
    {
        for (size_t j = 0; j < mySize; ++j)
        {
            ((int **)input)[i*mySize][j] = 10*i+j;
        }
    }
    return input;
}

int main(int argc, char const *argv[])
{
    size_t const mySize = 10;
    void * myMemory, * testPtr;

    myMemory = malloc(mySize * mySize * sizeof(int));

    testPtr = foo(myMemory, mySize);
    free(testPtr);
    return 0;
}

Теперь я подумал, что использование оператора [] будет таким же, как добавление int к указателю, например, что ((int **)input[i][j] будет таким же, как `((int **) input) +i + j

Но доступ к входному массиву в foo segfaults и использование gdb показывает мне

(gdb) p ((int **)input)[i][j]
Cannot access memory at address 0x0
(gdb) p ((int **)input)+i+j
$25 = (int **) 0x405260

, поэтому очевидно, что есть разница.И поэтому я в замешательстве.

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Хотя массивы и указатели похожи, они не одинаковы.

Массив - одно- или многомерный - отображает непрерывный кусок памяти, содержащий определенный тип данных.Например, int arr [10] объявляет arr как 10 непрерывных int с в памяти.int multi_arr[5][10] объявляет multi_arr как 5 массивов из 10 непрерывных int с в памяти.

Кроме того, имя arr будет базовым адресом этого массива, и передача его функции будеттак же, как прохождение &arr[0].

Но на этом сходство заканчивается.Многомерный массив не может ( технически ) быть приведен к указателю на указатель и затем снова обратно.

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

0 голосов
/ 15 декабря 2018

Вы разместили одномерный массив с элементами mySize * mySize.int ** - это массив указателей на int, который вам нужен:

int **array2d;
int *p;
array2D = malloc(ROWS * sizeof(int*) + ROWS * COLUMNS * sizeof(int));
p = (int*) &array2d[ROWS];
for (size_t i = 0; i < ROWS; ++i)
    array2d[i] = &p[i * COLUMNS];

теперь array2d [строка] [столбец] может работать.

Или, как уже было предложено, использовать одинразмерный массив и использовать формулы массива [row * COLUMNS + column].

...