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

Posted

技术标签:

【中文标题】返回意外值的指针/数组索引【英文标题】:Pointer/Array Indexing Returning Unexpected Values 【发布时间】:2021-02-17 14:58:57 【问题描述】:

我正在用 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 的第二个示例中做错了什么,在使用数组索引时得到了错误的值?

【问题讨论】:

我不知道为什么 -- 你的编译器工具集中有一个工具,那就是debugger。你没有提到你是否使用过调试器。 如果你一直使用索引,你会看到第一个打印y[n]两次,而第二个打印第一个y[n]然后y[0] 【参考方案1】:

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

【讨论】:

抱歉,我不太明白为什么会出现这个问题。如果y++ 只是增加指针,为什么当n 增加时它使y[n] 变成y[2n]?我认为这样做会使y 指向下一个数组索引,但是所有索引都可以访问,而无需考虑这一点,我猜情况并非如此。这就是为什么一旦我打印出main 中的整个数组,无论conv 是否工作,我都会得到正确的响应,因为导致索引问题的递增指针不再存在? 假设您将数组b 传递给y。当n 为3 时,yb+3。如果您随后访问y[3],那就是b[6]【参考方案2】:

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

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

你在增加y,所以y[n]会很快去奇怪的地方。

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

【讨论】:

以上是关于返回意外值的指针/数组索引的主要内容,如果未能解决你的问题,请参考以下文章

如何找到具有值的数组索引?

为啥 min_element() 返回最小元素的索引,而不是迭代器?

c语言中函数返回值可以是数组、字符串和结构体吗?

C++指针问题,请问如何定义一个返回值为结构体指针数组的函数?

Leetcode练习(Python):第162题:峰值元素是指其值大于左右相邻值的元素。 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。 数组

Python | 快速获取某一列数组中前 N 个最大值/最小值的索引 | 三种方法总结