从逆序 C++ 访问向量时出现运行时错误 [关闭]
Posted
技术标签:
【中文标题】从逆序 C++ 访问向量时出现运行时错误 [关闭]【英文标题】:Runtime error in accessing vector from reverse order C++ [closed] 【发布时间】:2020-01-09 19:42:31 【问题描述】:我试图以相反的顺序访问存储在向量中的值。以下代码显示没有错误:
for (long long int i = 0; i < end.size(); i++)
cout << end[end.size() - 1 - i] << "\n";
但以下代码显示运行时错误:
for(long long int i = end.size()-1;i>=0;i--) cout<<end[i]<<"\n";
这两种方法有区别吗?
【问题讨论】:
不相关,但 C++ 中的容器有rbegin
和 rend
(反向迭代器)。
我无法重现您的错误。你能准备一个minimal complete example吗?
这两种方法有什么区别吗? -- 在空向量上尝试第二种方法。
不要把你的向量称为end
,这只会让事情变得混乱。
【参考方案1】:
这两种方法有区别吗?
end.size()
返回std::size_t
,这是一个无符号类型。给定一个空向量,从无符号零中减去 1。由于无符号数使用模运算,结果是一个非常大的无符号数。
在这里,行为取决于语言的版本以及实现。如果long long
可以表示大的无符号值,那么您将使用这个大索引(任何索引超出空向量的范围)溢出数组,并且行为将是未定义的。这将发生在 32 位系统上,其中std::size_t
大概是 32 位和 long long 64 位。
如果 long long
无法表示该值,则在 C++20 之前,结果值将由实现定义。如果该值为负数,那么您有所需的行为,其他明智的未定义行为。在 C++20 之后,结果将与可表示值以可表示值的数量为模一致。如果long long
的位宽与std::size_t
匹配,则结果将为-1,并且行为将符合预期。
结论:后一种方法在某些实现上被破坏了。第一个没有这个问题。
【讨论】:
为什么是“理论上”?它只是坏了,不是吗? @foreknownas_463035818 在具有 2 的补码表示和long long
与 std::size_t
大小相同的系统上,它可以在实践中工作。这样的系统相当普遍。问题本质上在于与该描述不匹配的系统的可移植性。
@foreknownas_463035818 我从“理论上”删除了,因为我发现问题存在于所有 32 位或更小的系统上。【参考方案2】:
正确的做法是:
for(auto i=end.size(); i-- ;) cout << end[i] << "\n" ;
【讨论】:
不是,不是。正确的方法是使用反向迭代器。无论如何,您没有回答问题 那不是“正确”的推荐版本;它甚至不等价(它不打印第一个值)。以上是关于从逆序 C++ 访问向量时出现运行时错误 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
从成员函数打印 vector<int> 元素时出现 C++ 段错误
C++ vector 和 Gtkmm 能完美地协同工作吗?从 gtkmm on_click 方法获取向量<string> 的值时出现分段错误