访问 2D 向量数组时范围的分段 Fault/Out
Segmentation Fault/Out of Range on accessing a 2D vector array
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
int m, n;
cin>>m>>n;
vector <vector<char>> mine(n);
for( int i = 0; i < m; i++)
{
vector<char> row;
for( int i = 0; i < n ; i++)
{
char x;
cin>>x;
row.push_back(x);
}
}
cout<<mine.at(0).at(0)<<endl;
cout<<mine.at(-1).at(-1)<<endl;
cout<<mine.at(3).at(3)<<endl;
}
当我使用我的 [0][0] 而不是使用 at 成员函数时,我的代码在线上给出了分段错误。
cout<<mine.at(0).at(0)<<endl;
现在它给了我
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)
至于我为什么要访问-1 索引,我只是想检查向量是否会忽略它。虽然我不知道为什么它在访问第 0 个索引时遇到问题。
cout<<mine.at(0).at(0)<<endl;
尝试访问 mine
中第一个 vector<char>
的第一个元素,但第一个 vector<char>
不包含任何元素。这就是为什么在尝试使用 operator[]
访问该元素时出现分段错误,或者在尝试使用 at()
方法访问该元素时出现 std::out_of_range
异常。
您的代码有几个问题:
- 当您创建
mine
向量时,它只包含n
个空的vector<char>
。 - 然后在外部
for
循环的每次迭代中创建一个row
向量。但是该向量与mine
向量完全没有联系。此外,row
向量在外部for
循环的每个循环结束时被销毁。 - 当您打印出
mine
的内容时,mine
包含n
个空向量。mine.at(0)
将为您提供第一个空向量(如果n >= 1
),但mine.at(0).at(0)
将失败并出现超出范围的异常,因为第一个空向量中没有任何内容。-1
索引不会被忽略。 如果你看一下at
方法参考(https://en.cppreference.com/w/cpp/container/vector/at), you'll see that it receives astd::size_t
, an unsigned integer. So integer-1
is actually converted to a very large unsigned integer index. Check error message here: https://godbolt.org/z/xxfGhP7zq
如果 mine.at(3)
可能会失败,因为您正试图访问mine
处的第四个空向量。如果没有失败,mine.at(3).at(3)
将因与mine.at(0).at(0)
相同的原因而失败。在此处检查错误消息:https://godbolt.org/z/csz6TrYf4
n < 3
,
下面的代码解决了这些问题:https://godbolt.org/z/a63GrW8Tx
它创建了一个
mine
向量m
vector<char>
s 大小n
,即 spacen
个字符。在外部
for
循环中,它获取对mine[i]
的引用,当前vector<char>
.然后它用
row[j]
填充访问每个char
的向量。由于我们正在处理对mine
中向量的引用,因此我们正在修改mine
.我觉得对索引使用不同的名称更清楚。
我已经注释掉了超出范围的访问。如果你想避免它们,你应该根据向量大小检查你的索引。或者只处理异常。
#include <iostream> #include <string> #include <vector> int main() { int m; int n; std::cin >> m >> n; std::vector<std::vector<char>> mine(m, std::vector<char>(n)); for (int i{0}; i < m; i++) { auto& row = mine[i]; for (int j{0}; j < n ; j++) { char x; std::cin >> x; row[j] = x; } } std::cout << mine.at(0).at(0) << "\n"; //std::cout << mine.at(-1).at(-1) << "\n"; // out of range exception if (-1 < mine.size() and -1 < mine.at(-1).size()) { std::cout << mine.at(-1).at(-1) << "\n"; } //std::cout << mine.at(3).at(3) << "\n"; // out of range exception try { std::cout << mine.at(3).at(3) << "\n"; } catch (const std::out_of_range& ex) { std::cout << "Error: " << ex.what(); } }