向量下标超出函数范围

Posted

技术标签:

【中文标题】向量下标超出函数范围【英文标题】:Vector subscript out of range in function 【发布时间】:2020-07-28 22:04:04 【问题描述】:

我在这个背包函数中使用了一个二维向量,它不断返回超出范围的向量(第 1733 行),但是向量不应该超过它们的大小并导致溢出。将 for 循环更改为

int knapsack(int cap, vector<int>& weight, vector<int>& value, int n)

    vector<vector<int>> K;
    K.resize(cap, vector<int>(n));
    int i = 0;
    int j = 0;
    for (i = 0; i <= n; i++)
    
        for (j = 0; j <= cap; j++)
        
            if (i == 0 || j == 0)
                K[i][j] = 0;
            else if (weight[i - 1] <= j)
            
                K[i][j] = max(weight[i - 1] + K[i - 1][j - weight[i - 1]], K[i - 1][j]);
            
            else
            
                K[i][j] = K[i-1][j];
            
        
    

    return K[i][j];

据我了解,调整大小将是解决方案,但我已经使用向量大小的适当变量完成了该操作。还是我需要使用 pushback 代替?

【问题讨论】:

"向量不应该超过它们的大小并导致溢出" - 你当然认为你的程序是正确的,但是你和其他人一样会犯错误。您的向量是cap by n,但您将其索引为n by cap&lt;= 也是一个错误。 仅仅因为改变某些东西并不能解决问题并不意味着它不是错误。这只是意味着它不是唯一的错误。当你调试时,不要假设错误在哪里,因为你有一个错误首先表明你可能是错误的。 &lt;= 在 for 循环中总是引发我的蜘蛛感。 【参考方案1】:

矢量索引

当你声明K如下:

vector<vector<int>> K;
K.resize(cap, vector<int>(n));

那么向量K的长度为cap,每个向量K[i]的长度为n。但是,在您的 for 循环中,我看到:

for (i = 0; i <= n; i++)

    for (j = 0; j <= cap; j++)
    
        if (i == 0 || j == 0)
            K[i][j] = 0;
        ...
    

这里的索引顺序似乎是错误的,因为在if-statement 中,您可以设置K[n][0]K[0][cap - 1],此时唯一有效的最大索引是K[cap - 1][0]K[0][n - 1] .

使用push_back() 更安全。在这种情况下,不要忘记预留空间以避免不必要的重新分配。

循环范围

正如 cmets 中的其他人所提到的,在迭代 n 元素时,正确的写法是:

for (i = 0; i < cap; ++i)

所以没有'

循环结束后,迭代器将指向循环结束之外

一旦像for (i = 0; i &lt; cap; ++i) 这样的循环完成,它会将i 增加到值cap。所以最后一行:

return K[i][j];

肯定会访问超出范围的向量。你应该这样写:

return K[cap - 1][n - 1];

或者,您可以使用成员函数back() 访问向量的最后一个元素,并编写:

return K.back().back();

未使用的函数参数

为什么在这个函数中根本没有使用参数value

断言weight 具有正确的大小

访问超出范围的向量的另一个可能来源是向量weight 的大小不正确。您可以在代码中添加assert() 以在调试版本中发现此错误:

#include <cassert>
...
int knapsack(int cap, vector<int>& weight, vector<int>& value, int n)

    assert(weight.size() >= n - 1);
    ...

【讨论】:

所以我将它们反转为 K.resize(n, vector(cap)) 并且我仍然得到溢出。当我尝试在 for 循环中颠倒索引的顺序时,我遇到了同样的问题。 您的尺寸需要为 n+1cap+1,因为您的 for 循环使用 &lt;= 作为其限制

以上是关于向量下标超出函数范围的主要内容,如果未能解决你的问题,请参考以下文章

错误向量下标超出范围

向量下标超出范围错误 - C++ Vectors & Open CV

二维向量下标超出范围

调试断言失败,向量下标超出范围

opencv图像处理,向量下标超出范围

搜索字符串时向量下标超出范围