简体   繁体   English

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

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

Do I need to use size_t always when indexing an array even if the array is not big enough to exceed the size of an int?即使数组的大小不足以超过 int 的大小,在索引数组时是否需要始终使用size_t

It's not a question about when I should use size_t .这不是关于何时应该使用size_t I just want to know if, for example, a program having 2GB of available memory (all of these fields can be indexed by an int32) but with this memory being (virtual memory) assigned to the "fields" 14GB - 16GB of the computer's RAM.我只是想知道,例如,一个程序是否有 2GB 的可用内存(所有这些字段都可以由 int32 索引)但是这个内存(虚拟内存)分配给了计算机的 14GB - 16GB 的“字段”内存。

Would it always fail when indexing the memory if I used an int32 instead of a size_t (or an unsigned long int ) in this case?如果我在这种情况下使用int32而不是size_t (或unsigned long int )索引内存时它是否总是失败?

Maybe the question is more about virtual memory than about pointers.也许问题更多的是关于虚拟内存而不是指针。

size_t is an unsigned integer that is capable of holding the size of the largest object you can allocate. size_t是一个无符号整数,能够容纳您可以分配的最大对象的大小。 It is useful for indexing because this means it can index into the largest array you can allocate.它对索引很有用,因为这意味着它可以索引到您可以分配的最大数组。

This does not mean it is required or even necessarily recommended for indexing.这并不意味着它是索引所必需的,甚至是必须推荐的。 You can use any integer type that is large enough to index the array.您可以使用任何足够大的整数类型来索引数组。 int_fast32_t might be faster, uint_least16_t might be smaller in a structure, and so on. int_fast32_t可能更快, uint_least16_t在结构中可能更小,依此类推。 Know your data, and you can make a good choice.了解您的数据,您就可以做出明智的选择。

One consideration you should make is that on some platforms, using a signed index might require an extra sign extension instruction.您应该考虑的一个问题是,在某些平台上,使用签名索引可能需要额外的符号扩展指令。 As an example, here is x86:例如,这里是 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];
}

Virtual memory is outside the scope of C or C++.虚拟内存不在 C 或 C++ 的范围内。 From their point of view, you simply index into memory and it's up to your platform to make it work.从他们的角度来看,您只需对内存进行索引,这取决于您的平台使其工作。 In practice your app only uses virtual addresses;实际上,您的应用程序仅使用虚拟地址; your CPU/OS is translating the virtual address to a physical address behind the scenes.您的 CPU/OS 在幕后将虚拟地址转换为物理地址。 It is not something you need to worry about.这不是你需要担心的事情。

In order to avoid program failures the programmer should always use an index type that is at least as large as the type returned by the size() method.为了避免程序失败,程序员应该始终使用至少与size()方法返回的类型一样大的索引类型。 This ensures that the index never overflows any possible size of the array.这确保索引永远不会溢出数组的任何可能大小。 The implementation of an array is usually making sure that its runtime size never overflows the type returned by the size() method.数组的实现通常确保其运行时大小永远不会溢出size()方法返回的类型。 This means the index type should be:这意味着索引类型应该是:

  • size_t in case of char[N] , uint8_t[N] , int[N] , etc size_tchar[N]uint8_t[N]int[N]等情况下
  • size_t in case of std::vector and std::list size_tstd::vectorstd::list
  • int in case of QList and QVectorQListQVector情况下为int
  • an arbitrary precision integer (aint) in case of bitarrays (if the bitarray's size() method returns an aint)在位数组的情况下的任意精度整数 (aint)(如果位数组的size()方法返回 aint)
  • aint in case of arrays compressed in memory (if the array's size() method returns an aint) aint 在内存中压缩数组的情况下(如果数组的size()方法返回 aint)
  • aint in case of arrays spanning multiple machines (if the array's size() method returns an aint) aint 在数组跨越多台机器的情况下(如果数组的size()方法返回 aint)
  • Other languages than C++: C++ 以外的其他语言:
    • int in case of java.util.Collection and its subclasses intjava.util.Collection及其子类的情况下

In summary: A safe index type is the type returned by the size() method.总结:安全索引类型是size()方法返回的类型。

Note: If the size() method returns the unsigned size_t , then the signed int and ssize_t aren't safe index types.注意:如果size()方法返回无符号size_t ,则有符号intssize_t不是安全索引类型。 In case of gcc and clang, the compiler flags -Wsign-compare (enabled by -Wall ) and -Wconversion can be used to prevent most of these cases.在 gcc 和 clang 的情况下,编译器标志-Wsign-compare (由-Wall启用)和-Wconversion可用于防止大多数这些情况。

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

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