Cha*_*l72 9 c c++ pointers undefined-behavior language-lawyer
一些C或C++程序员惊讶地发现即使存储无效指针也是未定义的行为.但是,对于堆或堆栈数组,可以存储一个超过数组末尾的地址,这允许您存储"结束"位置以便在循环中使用.
但是从单个堆栈变量形成指针范围是未定义的行为,如:
char c = 'X';
char* begin = &c;
char* end = begin + 1;
for (; begin != end; ++begin) { /* do something */ }
Run Code Online (Sandbox Code Playgroud)
虽然上面的例子很没用,但是如果某个函数需要一个指针范围,那么这可能很有用,而且你有一个只有一个值来传递它的情况.
这是未定义的行为吗?
Ben*_*igt 14
这是允许的,则该行为被定义并且两者begin
和end
被安全地衍生的指针值.
在C++标准第5.7节([expr.add]
)第4段中:
出于这些运算符的目的,指向非阵列对象的指针与指向长度为1的数组的第一个元素的指针的行为相同,其中对象的类型为其元素类型.
使用C时,可以在C99/N1256标准6.5.6第7节中找到类似的条款.
出于这些运算符的目的,指向不是数组元素的对象的指针与指向长度为1的数组的第一个元素的指针的行为相同,其中对象的类型为其元素类型.
顺便说一下,在3.7.4.3节([basic.stc.dynamic.safety]
)"安全派生指针"中有一个脚注:
本节不对取消引用未分配的内存的指针施加限制
::operator new
.这保持了许多C++实现使用二进制库和用其他语言编写的组件的能力.特别是,这适用于C二进制文件,因为取消引用指向分配的内存的指针malloc
不受限制.
这表明整个堆栈中的指针算法是实现定义的行为,而不是未定义的行为.