繁体   English   中英

索引数组时我应该总是使用 size_t 吗?

[英]Should I always use size_t when indexing arrays?

即使数组的大小不足以超过 int 的大小,在索引数组时是否需要始终使用size_t

这不是关于何时应该使用size_t 我只是想知道,例如,一个程序是否有 2GB 的可用内存(所有这些字段都可以由 int32 索引)但是这个内存(虚拟内存)分配给了计算机的 14GB - 16GB 的“字段”内存。

如果我在这种情况下使用int32而不是size_t (或unsigned long int )索引内存时它是否总是失败?

也许问题更多的是关于虚拟内存而不是指针。

size_t是一个无符号整数,能够容纳您可以分配的最大对象的大小。 它对索引很有用,因为这意味着它可以索引到您可以分配的最大数组。

这并不意味着它是索引所必需的,甚至是必须推荐的。 您可以使用任何足够大的整数类型来索引数组。 int_fast32_t可能更快, uint_least16_t在结构中可能更小,依此类推。 了解您的数据,您就可以做出明智的选择。

您应该考虑的一个问题是,在某些平台上,使用签名索引可能需要额外的符号扩展指令。 例如,这里是 x86:

// movzx eax, BYTE PTR [rcx+rdx]
// ret
char get_index(char *ptr, unsigned idx)
{
   return ptr[idx];
}

// ; sign extending idx from 32 bits to 64 bits with movsx here.
// movsx rdx, edx     
// movzx eax, BYTE PTR [rcx+rdx]
// ret
char get_index(char *ptr, int idx)
{
   return ptr[idx];
}

虚拟内存不在 C 或 C++ 的范围内。 从他们的角度来看,您只需对内存进行索引,这取决于您的平台使其工作。 实际上,您的应用程序仅使用虚拟地址; 您的 CPU/OS 在幕后将虚拟地址转换为物理地址。 这不是你需要担心的事情。

为了避免程序失败,程序员应该始终使用至少与size()方法返回的类型一样大的索引类型。 这确保索引永远不会溢出数组的任何可能大小。 数组的实现通常确保其运行时大小永远不会溢出size()方法返回的类型。 这意味着索引类型应该是:

  • size_tchar[N]uint8_t[N]int[N]等情况下
  • size_tstd::vectorstd::list
  • QListQVector情况下为int
  • 在位数组的情况下的任意精度整数 (aint)(如果位数组的size()方法返回 aint)
  • aint 在内存中压缩数组的情况下(如果数组的size()方法返回 aint)
  • aint 在数组跨越多台机器的情况下(如果数组的size()方法返回 aint)
  • C++ 以外的其他语言:
    • intjava.util.Collection及其子类的情况下

总结:安全索引类型是size()方法返回的类型。

注意:如果size()方法返回无符号size_t ,则有符号intssize_t不是安全索引类型。 在 gcc 和 clang 的情况下,编译器标志-Wsign-compare (由-Wall启用)和-Wconversion可用于防止大多数这些情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM