使用数组时,标准算法(在C和C++中)通常会返回指向元素的指针.有时可以方便地获得元素的索引,也许是为了索引到另一个数组,我通常通过从指针中减去数组的开头来得到它:
int arr[100];
int *addressICareAbout = f(arr, 100);
size_t index = addressICareAbout - arr;
Run Code Online (Sandbox Code Playgroud)
这总是看起来简单而有效.然而,最近我指出,指针减法实际上返回a ptrdiff_t,原则上,如果" index"不适合a ,则可能存在问题ptrdiff_t.我真的不相信任何实施都会有足够的反复意义,允许人们创建如此大的arr(从而引起这样的问题),但是这里接受的答案承认这是可能的,而且我没有找到任何证据表明不这样做.因此,我已经辞职了(除非有人能说服我),并且会小心前进.这个答案提出了一种"安全"获取索引的相当复杂的方法; 真的没有更好的吗?
也就是说,我对C++中可能的解决方法感到困惑.我们有std::distance,但std::distance(arr, addressICareAbout)保证定义明确?一方面,(指向第一个元素的指针)arr可以递增到达addressICareAbout(右?),但另一方面std::distance应该返回a ptrdiff_t.标准容器的迭代器可能(可能)具有相同的问题.
你不可能有两个指向相同数组的指针,其差异不适合ptrdiff_t.
在64位实现上,ptrdiff_t被标记为64位,因此您需要一个80亿千兆字节的数组.在32位实现中,通常你的总地址空间限制为3 GB,如果幸运的话,它是3 1/4 GB(它的地址空间,而不是RAM,这很重要),所以你需要一个超过2 GB的数组,不会留下太多其他东西.并且很可能malloc将首先拒绝分配该大小的数组.你的判断当然.
虽然std :: distance具有优势,但我怀疑它与ptrdiff_t具有相同的理论问题,因为距离可以是正的和负的,并且在32位实现上它可能不是64位类型.
请注意,如果您可以在32位实现上分配3 GB数组,并且您对该数组的第一个和最后一个元素有两个int*,那么即使结果错误地计算指针差异,我也不会感到惊讶适合ptrdiff_t.