指针/数组索引返回意外值



我在c++中实现卷积的代码(我知道它已经存在,但我只是为了练习,因为我是初学者),虽然我可以得到正确的输出,但我正在尝试某些方法,这取决于我如何访问我存储在数组中的卷积值,我不知道为什么。无论我是通过数组索引还是指针递增来访问值,有效的函数代码是:

void conv(int M, int* h, int L, int* x, int* y) {
int n, m = 0;
for (n = 0; n < L + M - 1; n++) {
for (m = std::max(0, n - L + 1); m <= std::min(n, M - 1); m++) {
*(y+n) += *(h + m) * *(x + n - m);
};
std::cout << "using array index: " << std::endl;
std::cout << "n = " << n << " " << "y = " << y[n] << " " << std::endl;
std::cout << std::endl;
std::cout << "using pointer: " << std::endl;
std::cout << "n = " << n << " " << "y = " << *(y+n) << " " << std::endl;
std::cout << std::endl;
//y++;
}
}

但是,如果我对这个(下面编号)做了一点改动:

void conv(int M, int* h, int L, int* x, int* y) {
int n, m = 0;
for (n = 0; n < L + M - 1; n++) {
for (m = std::max(0, n - L + 1); m <= std::min(n, M - 1); m++) {
*y += *(h + m) * *(x + n - m); //[1]
};
std::cout << "using array index: " << std::endl;
std::cout << "n = " << n << " " << "y = " << y[n] << " " << std::endl;
std::cout << std::endl;
std::cout << "using pointer: " << std::endl;
std::cout << "n = " << n << " " << "y = " << *y << " " << std::endl; //[2]
std::cout << std::endl;
y++; //[3]
}
}

在这种情况下,只有通过指针访问值才能提供正确的输出,而通过数组索引访问它会提供随机的垃圾。

我的测试代码是:
int main()
{
const int M = 5; const int L = 6;
int y[M + L - 1] = {};
int x[L] = { 1, -2, 5, 3, 8, -4 };
int h[M] = { 1,2,3,4,5 };
int* yPtr = y; int* hPtr = h; int* xPtr = x;
conv(M, hPtr, L, xPtr, yPtr);
std::cout << "value after leaving conv" << std::endl;
for (int i = 0; i < M+L-1; i++) {
std::cout << "i = " << i << " " << "y = " <<  y[i] << std::endl;
}
}

总是提供正确的输出,即使在conv的for循环中访问数组元素时提供错误的输出。

为参考,正确输出为y = {1, 0, 4, 11, 26, 31, 53, 35, 24, -20}

我在conv的第二个例子中做错了什么在使用数组索引时获得错误的值?

在代码的第二个版本中,您在执行循环时增加y,因此第二个版本中的y[n]相当于第一个版本中的y[2*n]。一旦n达到数组的一半大小,y[n]就超过了数组的末端,因此是垃圾。*y等价于y[0]

你的例子很奇怪,有点难以阅读,但从你的第二个版本来看,这是可疑的:

std::cout << "n = " << n << " " << "y = " << y[n] << " " << std::endl;

你的y是递增的,所以y[n]会很快到达奇怪的地方。

我将Y保存为int * yOrig = y;,然后使用它,我想我得到了您期望的输出,但我不确定。

最新更新