如何解决使用2D向量时出现分割错误
我可以确切地知道为什么在我开始遍历或将输入输入2D向量时我的代码会出现分段错误吗?我不明白是什么引起了问题。
编辑:myvect[ans].push_back
是造成问题的部分。
所以我的问题是为什么它不只是向后推并在myvect [ans]位置创建矢量?这不是动态向量应该做的吗?
这是我的代码:
vector<vector<int>> myvect;
int ans = 2;
for(int i = 0; i < n; i++)
{
myvect[ans].push_back(i+1);
ans++;
}
for(int i = 0; i < myvect.size(); i++)
{
if(!myvect[i].empty())
{
for(auto x: myvect[i])
cout<<x<<" ";
}
}
解决方法
在您的代码中,您正在为myvect[ans]
之类的向量建立索引,但索引为ans
的元素可能不存在,即myvect.size() <= ans
,C ++默认不进行边界检查。因此,您将出现越界段错误。
C++
被设计为超级高效和快速。因此,在标准库的每个地方,如果程序员没有明确要求,C ++都不会进行检查。
只有Python或JavaScript这样的可脚本编写的语言一直都在进行检查,但这有时使它们比C ++慢100-200倍。
在std::vector
中有索引的边界检查变体,您必须使用myvect.at(and)
,它与myvect[ans]
相同,但是如果索引超出范围则抛出异常。但是请不要忘记使用try-catch
语法捕获异常。
但是.at()
方法仍然无法自动调整数组大小以添加新元素。为了具有自动调整大小的功能,您必须在向量类版本中自己实现该功能。
接下来,我已经编码了自动调整大小的版本。默认情况下,它也会在[]
运算符上将检查与检查绑定。您可以使用任何自定义行为来扩展标准C ++库中的任何类,就像我对下面的std::vector
所做的那样。
下一个代码的输出:
Trying VectorT == "Vector<Vector<int,std::allocator<int> >,std::allocator<Vector<int,std::allocator<int> > > >"
use_at == true
1 2 3
Trying VectorT == "Vector<Vector<int,std::allocator<int> > > >"
use_at == false
1 2 3
Trying VectorT == "std::vector<std::vector<int,std::allocator<std::vector<int,std::allocator<int> > > >"
use_at == true
Exception: vector::_M_range_check: __n (which is 2) >= this->size() (which is 0)
Trying VectorT == "std::vector<std::vector<int,std::allocator<int> > > >"
use_at == false
exited,segmentation fault
#include <vector>
#include <iostream>
#include <string>
#ifndef _MSC_VER
// Only for Unix demangling
#include <cxxabi.h>
#endif
using namespace std;
template < typename T,typename AllocatorT = typename std::vector<T>::allocator_type >
class Vector : public std::vector<T,AllocatorT> {
private:
typedef std::vector<T,AllocatorT> SuperT;
inline void FitSize(size_t i) {
if (i > SuperT::size())
SuperT::resize(i);
}
public:
template <typename ... Args>
Vector(Args ... args) : SuperT(args ...) {}
inline T & operator[] (size_t i) {
FitSize(i + 1);
return SuperT::operator[](i);
}
inline T const & operator[] (size_t i) const { return SuperT::at(i); }
inline T & at(size_t i) {
FitSize(i + 1);
return SuperT::at(i);
}
inline T const & at(size_t i) const { return SuperT::at(i); }
};
// This function is just for informational purposes of demangling
char const * Demangle(char const * name) {
#ifdef _MSC_VER
return name;
#else
int status = 0;
return abi::__cxa_demangle(name,&status);
#endif
}
template <template < typename T,typename AllocatorT = typename std::vector<T>::allocator_type > class VectorT>
void Test(bool use_at) {
try {
VectorT< VectorT<int> > myvect;
cout << "Trying VectorT == \"" << Demangle(typeid(myvect).name()) << "\"\n use_at == " << (use_at ? "true" : "false") << endl;
int ans = 2,n = 3;
for(int i = 0; i < n; i++)
{
if (!use_at)
myvect[ans].push_back(i+1);
else
myvect.at(ans).push_back(i+1);
ans++;
}
for(int i = 0; i < myvect.size(); i++)
{
if(!myvect[i].empty())
{
for(auto x: myvect[i])
cout << x << " ";
}
}
cout << endl;
} catch (exception const & ex) {
cerr << "Exception: " << ex.what() << endl;
} catch (...) {
cerr << "Unknown Exception!" << endl;
}
}
int main() {
Test<Vector>(true);
Test<Vector>(false);
Test<vector>(true);
Test<vector>(false);
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。