我想在某个循环中保存输入,创建对数组元素的引用,这可能不存在。这样做是否合法?一个简短的例子:
#include<vector>
#include<iostream>
#include<initializer_list>
using namespace std;
int main(void){
vector<int> nn={0,1,2,3,4};
for(size_t i=0; i<10; i++){
int& n(nn[i]); // this is just to save typing, and is not used if invalid
if(i<nn.size()) cout<<n<<endl;
}
};
https://ideone.com/nJGKdW编译并运行代码就好了(我用g ++和clang ++在本地尝试过),但我不确定我是否可以依赖它。
PS:即使在使用-Wall
和-g
进行编译+运行时,gcc也没有抱怨。
编辑2:讨论的重点是数组索引。实际代码实际使用std::list
,片段看起来像这样:
std::list<int> l;
// the list contains something or not, don't know yet
const int& i(*l.begin());
if(!l.empty()) /* use i here */ ;
编辑3:我正在做的事情的法律解决方案是使用迭代器:
std::list<int> l;
const std::list<int>::iterator I(l.begin()); // if empty, I==l.end()
if(!l.empty()) /* use (*I) here */ ;
答案 0 :(得分:3)
不,不合法。您正在使用n
声明中的向量读取数据,因此您的程序具有未定义的行为。
答案 1 :(得分:0)
如果规范“允许”,我会感到惊讶。但是,它所做的是存储超出其分配范围的元素的地址,在大多数情况下本身不应该导致问题 - 在极端情况下,它可能会溢出指针类型,这可能会导致问题,我想。
换句话说,如果i
超出nn
的大小,则可能是一个问题,不一定要说i
必须是巨大的 - 如果向量中的每个元素是几兆字节(或64位计算机中的千兆字节),您可以很快遇到地址范围问题。
但是不要让我引用规范 - 别人可能会这样做。
编辑:根据评论,由于您要求的值超出有效大小的地址,至少在调试版本中,这可能会导致vector
实现断言或以其他方式“警告您是错的”。
答案 2 :(得分:0)
不,有两个原因:
标准状态(8.3.2):
应初始化引用以引用有效的对象或函数
std::vector::operator[]
保证即使N
超过容器大小,该函数也不会抛出异常(无抛出保证,除at()
以外没有边界检查)。但是,在这种情况下,行为未定义。
因此,您的程序格式不正确(项目符号1)并调用未定义的行为(项目符号2)。