double expressionB = **(ppDoubleArray + 1);
Давайте посмотрим на память этого парня, в стеке у вас есть указатель на указатель на двойное число. Так что, если это адрес в памяти для 32-битного процессора, стек может выглядеть примерно так:
stack: |ppDoubleArray ptr |local vars, other args, or garbage |more locals/etc
addr: |0 bytes from stack |4 bytes from stack |8bytes...
Итак, когда мы смотрим на первую часть выражения
(ppDoubleArray + 1)
Здесь написано "пройти один указатель мимо ppDoubleArray
". Перейти к следующему указателю, перейдя к следующему месту в памяти. Какая следующая точка в памяти после ppDoubleArray
? Посмотрите на стек выше, это, вероятно, некоторые локальные переменные или другой аргумент. Итак, теперь у вас есть кто знает, что (возможно, содержимое длины? Один из двойников? Мусор?), И вы будете обращаться с ним, как если бы это был допустимый адрес где-то. Затем вы следуете этому предполагаемому указателю, разыменовывая:
**(ppDoubleArray + 1)
И сбой!
Так, например, если длина равна 5, ppDoubleArray + 1 может получить 5 и разыменовать «5», ища что-то по этому адресу.
Этот код:
double expressionC = *ppDoubleArray[i];
работает так же, []
имеет приоритет над разыменованием. Итак, вы идете в i-ю ячейку памяти после ppDoubleArray
и предполагаете, что она указывает на ваш массив.
Изменение порядка операций с родителем будет работать:
(*ppDoubleArray)[i]