3

在Andrey Karpov 题为“关于的这篇博客文章中,size_tptrdiff_t他展示了一个例子,

for (ptrdiff_t i = 0; i < n; i++)
  a[i] = 0;

但是,我不确定这是否正确,似乎应该是

for (size_t i = 0; i < n; i++)
  a[i] = 0;

这个对吗?

我知道我们也应该使用类似的东西memset,但让我们完全避免这种情况。我只问类型

4

3 回答 3

8

一篇博文中,我认为您应该始终避免分配大于PTRDIFF_MAX(*) 的内存块,因为这样做会使诸如 Clang 和 GCC 之类的编译器生成无意义的代码,即使您不以某种方式减去指向该块的指针导致结果溢出。

(*) 即使malloc当你传递一个大于PTRDIFF_MAX. 问题的症结在于 GCC 和 Clang 只生成在与这样mallocmalloc.

如果您遵循该约束(我鼓励您这样做:这是博客文章的信息),那么这两种类型都是同样正确的。

这就是说,由于只需要表示正偏移量,size_t因此在您的示例中将是自然选择。

于 2018-07-07T22:00:11.557 回答
2

可以使用 of ptrdiff_t,因为a[i]被翻译为*(a + i).

如果您采用两个指针p1p2,建议您使用:

ptrdiff_t d = p2 - p1; // Assuming p2 - p1 is valid.

鉴于此,p2 == p1 + d, ie<ptr type> + ptrdiff_t是一个有效的表达式。索引类型是否更好取决于团队中使用的意见和/或编码风格ptrdiff_tsize_t

于 2018-07-07T22:26:13.957 回答
0

OP 问题的答案是肯定的,size_t 最适合示例代码,其中没有相互减去指针值,并且没有围绕malloc行为的交叉编译器/库兼容性问题。不管堆管理器有什么不同,在 C 中,数组SIZE_MAX的长度可以是字节,并且需要 asize_t来表示它。标准中的任何内容都不需要堆管理器能够分配堆中的所有进程内存空间,或者为此分配最多SIZE_MAX字节,但是数组可以是SIZE_MAX长度,因此size_t是合适的。

即使n已签名,使用ptrdiff_tfori也无济于事,因为初始i < n测试无论如何都会失败,如果n为负,因为i已初始化为零。没有索引无法访问i的索引。size_t唯一ptrdiff_t需要的地方是从另一个指针值中减去一个指针值,而 OP 并没有询问这一点。

于 2018-07-08T00:21:31.793 回答