доступ к многомерному массиву C через синтаксис массива против арифметики указателя

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

int main()
{
    int** arr = malloc(
        3 * sizeof(int*)
    );
    for(int y = 0; y < 3; y++) {
        int* subarr = malloc(
            3 * sizeof(int)
        );
        for(int x = 0; x < 3; x++) {
            subarr[x] = y * 3 + x + 1;
        }
        arr[y] = subarr;
    }
    printf("%d\n", *(&arr[0][0]) + 3);
    printf("%d\n", (&arr[0][0])[3]);
}

Может ли кто-нибудь объяснить, что здесь происходит / что мне не хватает?


person ZombieTfk    schedule 26.04.2020    source источник
comment
x[3] и *(x+3) одинаковы, но ваш первый отпечаток (*x) + 3, который отличается   -  person M.M    schedule 27.04.2020
comment
также (&arr[0][0])[3] доступ за пределы (вызывая неопределенное поведение)   -  person M.M    schedule 27.04.2020
comment
Хорошо, это объясняет, почему они оценивают разные ценности. Да, я не был уверен, законно или нет пытаться получить доступ к следующему подмассиву с помощью оператора доступа к массиву вне границ, так что я думаю, это ответит на оба моих вопроса, спасибо.   -  person ZombieTfk    schedule 27.04.2020


Ответы (1)


Прежде всего, позвольте мне объяснить, что вы делаете (по крайней мере, для меня).

arr[0] = A pointer to array {1, 2, 3}
arr[1] = A pointer to array {4, 5, 6}
arr[2] = A pointer to array {7, 8, 9}

Первый случай: *(&arr[0][0]) + 3

&arr[0][0] = Address of first element of {1, 2, 3}
*(&arr[0][0]) = 1      // Dereferencing the address 

Итак, он печатает 1 + 3 = 4

Второй случай: (&arr[0][0])[3]

(&arr[0][0]) = Address of first element of {1, 2, 3}

Но длина массива равна 3, поэтому вы можете получить доступ только к индексам до 2. Таким образом, это вызывает неопределенное поведение.

person CITIZENDOT    schedule 16.06.2020