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