C++标准[sec 5.7]说:
如果指针操作数和结果指向相同的数组对象,或一个过去的数组对象的最后一个元素的元素两者,所述评估也不得产生溢出; 否则,行为未定义.
那么,我是否正确地假设其他类型的指针比数组未定义?
例如:
int a = 0;
vector<int> v(&a, (&a)+1);
Run Code Online (Sandbox Code Playgroud)
上面的代码片段编译并且工作正常(使用g ++),但它是否有效?
序言: 众所周知,将指针放在数组末尾之后是合法且明确定义的:
int main()
{
int na [1] = {};
const int* naBegin = na;
const int* naEnd = na + 1; // one-past-end, OK
}
Run Code Online (Sandbox Code Playgroud)
此指针可用于比较,这有助于C样式数组(或更准确地说,其中的指针)与采用迭代器的标准库例程兼容,例如copy(Live Demo):
template <typename Field, typename Iter>
void foo(Iter begin, Iter end)
{
std::copy (begin, end, std::ostream_iterator <Field> (std::cout, std::endl);
}
int main()
{
int na [1] = {};
foo <int> (na, na + 1);
}
Run Code Online (Sandbox Code Playgroud)
标准(C++ 03参考)支持其合法性和定义性:
5 /当一个具有整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型.如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向偏离原始元素的元素,使得结果元素和原始数组元素的下标的差异等于整数表达式.换句话说,如果表达式P指向数组对象的第i个元素,则表达式(P)+ N(等效地,N +(P))和(P)-N(其中N具有值n)指向分别为数组对象的第i + n和第i-n个元素,只要它们存在.此外,如果表达式P指向数组对象的最后一个元素,则表达式(P)+1指向一个超过数组对象的最后一个元素,如果表达式Q指向一个超过数组对象的最后一个元素,表达式(Q)-1指向数组对象的最后一个元素.如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义.
当我在标准中查看对过去指针的浊度的引用时,我发现的每个引用都在讨论数组.如果我们试图将对象的地址过去,而不是数组呢?
问题: …
请考虑以下代码:
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
string myAry[] =
{
"Mary",
"had",
"a",
"Little",
"Lamb"
};
const size_t numStrs = sizeof(myStr)/sizeof(myAry[0]);
vector<string> myVec(&myAry[0], &myAry[numStrs]);
copy( myVec.begin(), myVec.end(), ostream_iterator<string>(cout, " "));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里感兴趣的是&myAry[numStrs]:numStrs等于5,所以&myAry[numStrs]指向不存在的东西; 数组中的第六个元素.在上面的代码中有另一个例子: myVec.end()它指向向量的一个结尾myVec.获取不存在的此元素的地址是完全合法的.我们知道它的大小string,所以我们知道C型数组的string第6个元素的地址必须指向何处.只要我们只评估这个指针并且从不取消引用它,我们就没事了.我们甚至可以将它与其他指向相等的指针进行比较.STL一直在处理一系列迭代器的算法中执行此操作.该end()迭代器指向过去的结束,以及循环,同时保持一个计数器循环!= end().
所以现在考虑一下:
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int …Run Code Online (Sandbox Code Playgroud)