超过矢量不会引起区段故障
exceeding vector does not cause seg fault
我对这段代码的结果感到非常困惑:
std::vector<int> v;
std::cout << (v.end() - v.begin()) << std::endl;
v.reserve(1);
std::cout << (v.end() - v.begin()) << std::endl;
v[9] = 0;
std::cout << (v.end() - v.begin()) << std::endl;
输出:0
0
0
所以…首先……end()
不指向内部数组的末端,而是指向最后一个被占用的cell…这就是为什么迭代器的减法结果在reserve(1)
之后仍然是0
。但是,为什么一个细胞被填满后仍然是0
。我期望结果是1
,因为end()
现在应该将迭代器返回到第二个内部数组单元格。此外,为什么在地球上我没有得到一个segfault访问第十个细胞与v[9] = 0
,而矢量只有1个细胞长?
首先,end()
为您提供了指向vector中最后一个元素之后的迭代器。如果vector为空,则begin()
只能返回与end()
相同的值。
当你调用reserve()
时,你实际上并没有创建任何元素,你只是保留了一些内存,这样当你添加元素时,向量就不必重新分配了。
最后,当你做
v[9] = 0;
您正在索引向量超出边界,这导致未定义行为当您写入不属于您的内存时。UB经常导致崩溃,但它没有,它可能看起来工作,而实际上它不起作用。
作为最后一部分的注释,[]
运算符没有边界检查,这就是为什么它会接受超出边界的索引。如果你想要边界检查,你应该使用at()
。
v[9] = 0;
,你只是访问了边界外的向量,它是UB。它在某些情况下可能会崩溃,也可能不会。
和v[9] = 0;
,你根本不添加元素。您需要使用push_back
或resize
:
v.push_back(0); // now it has 1 element
v.resize(10); // now it has 10 elements
编辑
为什么v[index]没有创建一个元素?
因为std::vector::operator[]不能做到这一点
返回对指定位置pos的元素的引用。不执行边界检查。与std::map::operator[]不同,此操作符从不向容器中插入新元素。
因此假定该向量有足够的元素来进行下标操作。
BTW:当你写v[9] = 0
时,你认为vector应该做什么?在将第10个元素设置为0
之前,它必须先压入10个元素。如何设定他们的价值观?所有0
?所以,它不会这样做,问题只是取决于你自己。
这是一个猜测,但希望对您有所帮助。
当你试图访问一个没有分配给进程内存空间的地址时,你只会得到一个段错误。当操作系统为程序提供内存时,它通常以4KB为增量。因此,您可以访问超过结尾的一些数组/向量而不会触发段错误,但不能访问其他的。
- Python & C-C++ 扩展模块案例段故障
- 中断;导致段故障
- 带指针的调用函数会导致段故障
- 由于变量范围导致的段故障
- 为什么通过shared_from_this()会导致段故障
- 简单的C++字符数组加密功能 - 段故障
- std::vector的函数push_back中的堰段故障
- 位字段 keil 重新启动后硬故障
- 在openCV中将cvPoint[][]转换为cvPoint**时出现段故障
- 模板变量分配段故障11
- CIN 一个非常大的 int 数组,段故障 11
- C++段故障错误
- 段故障 -> 在标准::basic_ostream<字符中,标准::char_traits<char>
- C++中的二叉树段故障
- 调试执行工作正常,但正常的一段故障
- c++:几乎相同的输入,但第二次调用显示段故障
- 段故障。地址0x0不是堆叠的、恶意的或(最近)释放的
- 使用矢量引起的段故障
- 使用arm-linux- gnuabi -g++ -o时出现段故障,不使用-o也不会出现问题
- 为什么会出现以下段故障