所以我有一个函数返回一个指向数组A中元素的指针。我有另一个函数将该指针作为参数。但是,我需要该函数来处理它可能传递完全任意指针的可能性。
有没有办法能够检测指针是否指向结构中的某个位置?在这种情况下,我的数组A?
我看过类似的关于C ++的问题,但没有看到C。
答案 0 :(得分:3)
唯一可移植的方法是对指针的所有可能有效值使用相等性测试。例如:
int A[10];
bool points_to_A(int *ptr)
{
for (int i = 0; i < 10; ++i)
if ( ptr == &A[i] )
return true;
return false;
}
请注意,使用带有两个指针的关系运算符(例如<
)或减法是未定义的行为,除非两个指针实际指向同一数组的元素(或者一个超过结尾的元素)。
答案 1 :(得分:1)
在§6.5.8关系运算符一节中,C11标准(ISO / IEC 9899:2011)说:
当比较两个指针时,结果取决于指向的对象的地址空间中的相对位置。如果两个指向对象类型的指针都指向同一个对象,或者两个指针都指向同一个数组对象的最后一个元素,则它们相等。如果指向的对象是同一聚合对象的成员,则指向稍后声明的结构成员的指针比指向结构中先前声明的成员的指针要大,指向具有较大下标值的数组元素的指针比指向同一数组的元素的指针要大。具有较低的下标值。指向同一个union对象的成员的所有指针都比较相等。如果表达式
P
指向数组对象的元素,并且表达式Q
指向同一数组对象的最后一个元素,则指针表达式Q+1
比较大于P
。在所有其他情况下,行为未定义。
如果您知道指针在数组范围内,那么比较就可以了。如果指针超出范围,则无法确定比较是否有效。在实践中,它通常会这样做,但标准明确指出比较会产生未定义的行为。
请注意,对于数组SomeType array[20];
,地址&array[20]
保证有效,并可与&array[0]
到&array[19]
的任何地址进行可靠比较。您需要决定是否要将其计入数组中。
根据观察标准不能保证它能够起作用,那么,你可以比较两个int
指针:
int within_int_array(int *array, size_t num_ints, int *ptr)
{
return ptr >= array && ptr < array + num_ints;
}
现在,您应该越来越谨慎地调用未定义的行为。编译器对使用未定义行为的程序做了讨厌的事情,从技术上讲,你没有追索权,因为标准说“未定义的行为”。