指针减法和替代 [英] Pointer Subtraction and an Alternative

查看:93
本文介绍了指针减法和替代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用数组时,标准算法(在C和C ++中)通常返回指向元素的指针。有时候方便的是获得元素的索引,也许是索引到另一个数组,我通常从指针中减去数组的开始:

When working with arrays, standard algorithms (in both C and C++) often return pointers to elements. It is sometimes convenient to have the index of the element, perhaps to index into another array, and I normally get that by subtracting the beginning of the array from the pointer:

int arr[100];
int *addressICareAbout = f(arr, 100);
size_t index = addressICareAbout - arr;

这总是看起来简单而有效。但是,最近我指出指针减法实际上返回一个 ptrdiff_t ,原则上,如果 index 不适合 ptrdiff_t 。我没有真正相信任何实现将是不正当的,足以允许创建这样大的arr(从而导致这样的问题),但接受的答案在这里承认这是可能的,我没有发现没有证据表明,否则。因此,我已经离开了这种情况(除非有人可以说服我,否则),并会小心前进。这个答案提出了一个安全获得索引的相当复杂的方法;是真的没有什么更好吗?

This always seemed simple and effective enough. However, it was recently pointed out to me that pointer subtraction actually returns a ptrdiff_t and that, in principle, there could be problems if the "index" doesn't fit in a ptrdiff_t. I didn't really believe that any implementation would be perverse enough to allow one to create such a large arr (and thereby cause such issues), but the accepted answer here admits that that's possible and I've found no evidence to suggest otherwise. I've therefore resigned myself to this being the case (unless someone can convince me otherwise) and will be careful going forward. That answer proposes a fairly convoluted method of "safely" getting the index; is there really nothing better?

这就是说,我困惑了一个可能的解决方法在C + +。我们有 std :: distance ,但是 std :: distance(arr,addressICareAbout)定义?一方面,( arr 的第一个元素的指针)可以递增到 addressICareAbout ),但另一方面 std :: distance 应该返回一个 ptrdiff_t 。标准容器的迭代器可以(可能)有相同的问题。

That said, I'm confused about a possible workaround in C++. There we have std::distance, but is std::distance(arr, addressICareAbout) guaranteed to be well-defined? On the one hand, (the pointer to the first element of) arr can be incremented to reach addressICareAbout (right?), but on the other hand std::distance should return a ptrdiff_t. The iterators for the standard containers can (presumably) have the same issues.

推荐答案

指向同一数组的指针,其中差异不适合ptrdiff_t。

It is extremely unlikely that you will ever have two pointers to the same array where the difference doesn't fit into ptrdiff_t.

在64位实现上,ptrdiff_t是64位的,所以你需要一个80亿吉字节的数组。在32位实现上,通常你的总地址空间被限制为3 GB,3 1/4 GB,如果你是幸运的(它的地址空间,而不是RAM),所以你需要一个超过2 GB的数组不会留下任何其他东西。很可能malloc将首先拒绝分配那个大小的数组。你的判断当然。

On 64 bit implementations, ptrdiff_t is signed 64 bit, so you'd need an array of 8 billion gigabytes. On 32 bit implementations, usually your total address space is limited to 3 GB, 3 1/4 GB if you are lucky (it's address space, not RAM, that counts), so you'd need an array of more than 2 GB which doesn't leave much for anything else. And it is quite possible that malloc will refuse to allocate an array of that size in the first place. Your judgement of course.

虽然std :: distance有优点,我怀疑它有与ptrdiff_t相同的理论问题,因为距离可以是正和负,它可能不是64位类型在32位实现。

While std::distance has advantages, I suspect it has the same theoretical problem as ptrdiff_t, since distances can be positive and negative, and it's probably not a 64 bit type on a 32 bit implementation.

请注意,如果您可以在32位实现上分配一个3 GB的数组,并且该数组的第一个和最后一个元素有两个int *如果指针差异计算不正确,即使结果符合ptrdiff_t,也不会感到惊讶。

Note that if you can allocate a 3 GB array on a 32 bit implementation, and you have two int* to the first and the last element of that array, I wouldn't be surprised if the pointer difference is calculated incorrectly even though the result fits into ptrdiff_t.

这篇关于指针减法和替代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆