检查指针是否指向标准C / C ++中的数组

时间:2012-06-22 22:17:12

标签: c++ c pointers

  

可能重复:
  checking if pointer points within an array

如果我有一个数组和一个大小,并且我想检查给定指针是否指向数组内的元素,那么在没有调用UB的情况下,有没有办法在标准C或C ++中这样做?

这有用吗?

bool is_inside(someType * array, int size, someType * other_pointer){
    for (int i = 0; i < size; i++)
        if (array + i == other_pointer)
            return true;
    return false;
}

编辑:我的理解是,除了==!=之外,你不能使用不指向同一个数组而没有UB的指针(尽管在实践中它按预期工作)。我错了吗?

5 个答案:

答案 0 :(得分:3)

保证数组在内存中是连续的,所以只需检查指针是否在第一个元素和最后一个元素的地址范围内。

答案 1 :(得分:2)

bool is_inside(someType * array, int size, someType * other_pointer) {
  return array <= other_pointer && other_pointer < array + size;
}

答案 2 :(得分:1)

您的解决方案可行,但不是最佳,因为它包含不必要的循环。

你应该做的是获取指向数组的指针,数组大小(以字节为单位),并检查指向的地址是否落在该数组占用的地址空间内。

答案 3 :(得分:1)

您可以简单地写一下:

bool inside = (other_pointer >= array) && (other_pointer < array+size);

这是合法检查。

答案 4 :(得分:1)

这取决于你对UB的意思。

具体来说,对于指针比较,C ++标准的第5.9节“关系运算符”说:

  

如果同一类型的两个指针p和q指向不同的对象   不是同一个对象或不同功能的成员,或者只是其中一个   它们为空,p<qp>qp<=qp>=q的结果未指定。

请注意,行为是未指定(意味着比较的结果可能是truefalse - 换句话说,结果并不能告诉您任何有用的信息 - 但是实现不需要指定哪个)而不是 undefined (意味着编译器或生成的程序可以做任何事情)。

然而,到目前为止,我只看到一系列的实现没有使用像Kirill这样的代码执行预期的操作:

bool inside = (other_pointer >= array) && (other_pointer < array+size);

这些实现是用于构建MS-DOS实模式程序的编译器,其中地址具有段落和偏移部分。地址FF00:0010和FF01:0000指向相同的内存位置,但如果我没记错,编译器不能保证以预期的方式运行,除非编译某些内存模型(当然 HUGE 模型,但也许是其他人。)

但是,如果pq没有指向现有对象(因为例如指针被释放),那么无论你做什么,行为都将是不确定的。因此,您无法使用这种方法来确定指针是否仍然有效。