1

我试图理解一些以我不习惯的方式使用指针算术的代码。在代码中的某一时刻,我遇到了这个:

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]);

我一直在寻找关于这里发生了什么的解释,但我找不到。此外,有问题的代码最终显然给出了正确的结果(它是蒙特卡洛的一部分)。有任何想法吗?

4

2 回答 2

2

您发布的代码是错误的;它确实调用了未定义的行为。

例如。在第二次迭代中,p_row(*P)+n*P指向一个大小为 的数组n,因此,当代码读取 时*(p_row+i),它会读取到数组的末尾。

最后一行似乎假设矩阵存储在单个连续数组中(例如,主要行)。但是,这意味着P将由complex<double>*初始化P = new complex<double>[n*n];

于 2012-10-26T16:30:38.033 回答
2

具有未定义行为的循环p_row+=n,因为它假定循环在第三行完成的分配是连续的,但在几乎所有实现中它们都不是。

您的代码P[i][i]检索正确的结果。n*n您可以通过一次性分配元素,然后将它们打包成p一个循环来修复其他代码。

于 2012-10-26T16:31:01.203 回答