Арифметика указателей в цикле for

Я пытаюсь понять некоторый код, который использует арифметику указателей так, как я не привык. В одном месте кода я сталкиваюсь с этим:

complex<double> **P, *p_row, result=complex<double>(0,0);
P=new complex<double>*[n];
for(i=0;i<n;i++) P[i]=new complex<double>[n];

for(i=0,p_row=*P;i<n;i++,p_row+=n) result+=log(*(p_row+i));

Если P — матрица, это выглядит как добавление логарифмов диагональных элементов P. Но оказывается, что последняя строка выше не эквивалентно

for(i=0;i<n;i++) result+=log(P[i][i]);

Я искал объяснение того, что здесь происходит, но я не могу его найти. Кроме того, рассматриваемый код, очевидно, дает правильный результат в конце (это часть Монте-Карло). Есть идеи?

1

Решение

Код, который вы опубликовали, неверен; это вызывает неопределенное поведение.

Например. во второй итерации, p_row является (*P)+n, *P указывает на массив размера nследовательно, когда код читает *(p_row+i), он читает за концом массива.

Кажется, в последней строке предполагается, что матрица хранится в одном непрерывном массиве (например, основной ряд). Однако это означает P будет complex<double>* инициализируется P = new complex<double>[n*n];,

2

Другие решения

Цикл с p_row+=n демонстрирует неопределенное поведение, поскольку предполагает, что выделения, выполняемые циклом в третьей строке, являются смежными, но почти во всех реализациях это не так.

Ваш код с P[i][i] получает правильный результат. Вы можете исправить другой код, выделив n*n элементы в одном кадре, а затем разложить их в p в петле.

2

По вопросам рекламы [email protected]