C++ 检查指针是否指向标准C/C++;

C++ 检查指针是否指向标准C/C++;,c++,c,pointers,C++,C,Pointers,可能重复: 如果我有一个数组和一个大小,我想检查一个给定的指针是否指向数组中的一个元素,那么在没有调用ub?< /p>的情况下,在标准的C或C++中有没有这样的方法? 这行吗 bool is_inside(someType * array, int size, someType * other_pointer){ for (int i = 0; i < size; i++) if (array + i == other_pointer) r

可能重复:

如果我有一个数组和一个大小,我想检查一个给定的指针是否指向数组中的一个元素,那么在没有调用ub?< /p>的情况下,在标准的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;
}
bool在内部(someType*数组、int大小、someType*其他指针){
对于(int i=0;i

编辑:据我所知,您不能使用除
==
之外的比较=
用于指针不指向同一个没有UB的数组(尽管在实践中它可以按预期工作)。我错了吗?

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

您的解决方案可以工作,但不是最优的,因为它包含一个不必要的循环

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

您只需编写:

bool inside = (other_pointer >= array) && (other_pointer < array+size);
bool-inside=(其他指针>=数组)和&(其他指针<数组+大小);

这是法律检查。

这取决于你所说的UB是什么意思

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

如果同一类型的两个指针p和q指向不同的对象 不是同一对象的成员或不同函数的成员,或者如果只有一个 它们为空,
pq
p=q
的结果未指定

请注意,行为是未指定的(这意味着比较的结果可能是
true
false
——换句话说,结果不会告诉您任何有用的信息——但实现不需要指定哪些内容),而不是未定义的(这意味着编译器或生成的程序可以做任何事情)

然而,到目前为止,我只看到了一系列实现,这些实现没有像Kirill的代码那样实现预期的功能:

bool inside = (other_pointer >= array) && (other_pointer < array+size);
bool-inside=(其他指针>=数组)和&(其他指针<数组+大小);
这些实现是用于构建MS-DOS实模式程序的编译器,其中地址有一个段落和偏移部分。地址FF00:0010和FF01:0000指向同一个内存位置,但如果我回忆正确,编译器不能保证以预期方式运行,除非编译某些内存模型(当然是大型模型,但也可能是其他模型)



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

那么你测试过它了吗?它有效吗?@Astor测试不是确保它“不调用UB”工作的好方法@R.MartinhoFernandes--这可能实际上并不指向数组中的元素。@R.MartinhoFernandes如果你这样说的话,我想你是对的。@R.MartinhoFernandes关于:
类型ta[5];
类型tb;
在(a,5,&b)里面吗;
还应检查指针和数组地址之间的差异是否为
sizeof(someType)
的倍数。元素大小是不必要的(提示:参数中提到了
someType
).@Alex这只是数组本身从一个地址开始的情况,该地址是
sizeof(someType)
的倍数。指向数组元素的“中间”不是一件好事,不管数组从哪里开始。@zxcdw:不。你不应该关心无效指针(面对它们你也不能做任何明智的事情)。如果向您传递了一个无效指针,则该行为已未定义,因为您必须首先调用UB以获取无效指针。还应检查指针与数组地址之间的差值是否为sizeof(someType)的倍数
@Alex:事实上,我不同意。正如R.Martinho Fernandes所说,这将是一个无效指针。对于无效指针,您不希望函数返回true。@Alex:我不认为返回false更好。为什么一开始就有一个无效指针?我想说的是未定义的行为,我甚至不想指定什么你知道哪些函数在传递一个无效指针时指定了它们的行为?在大多数C和C++的实际实现中,魔术UB并不是那么神奇,指针只是CPU作为地址使用的数字。如果你写的东西类似内核系统调用函数,你真的很想检查T。his,无论语言标准是否告诉您它已经存在UB或将存在UB。还应检查指针和数组地址之间的差异是否是
sizeof(someType)
的倍数。此外,还要注意加法和减法的溢出。@Alex如果指针操作数和结果都指向同一数组对象的元素,或超过数组对象的最后一个元素,则计算不应产生溢出;否则,行为未定义。“根据§5.7/6,假设给定的大小不正确,该函数的唯一合理实现是
std::terminate()
。你无能为力。@JonathanWakely:我认为指针的
std::less
只能保证是一个适合在集合中使用的顺序,等等。它不能保证适合确定和对象是否是数组的元素。数组可以交错出现。FF00:0000转换为FF00*10+0000=FF000,而FF:0000转换为FF00*10+0000=FF000001:0010会翻译的,我