C++ 中 size_t 和 int 有什么区别?
在几个 C++ 示例中,我看到使用了 size_t
类型,而我本来会使用简单的 int
类型。 有什么区别,为什么 size_t
应该更好?
In several C++ examples I see a use of the type size_t
where I would have used a simple int
. What's the difference, and why size_t
should be better?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
来自友好的维基百科:
另外,请检查为什么 size_t 很重要
From the friendly Wikipedia:
Also, check Why size_t matters
size_t
1) 是用于表示大小的数据类型(顾名思义),2) 取决于平台(甚至可能是实现) ,因此它应该仅用于表示尺寸。表示尺寸,
size_t
自然是无符号的(你能有一个负3米宽的盒子吗?)。 许多 stdlib 函数,包括 malloc、sizeof 和各种字符串操作函数都使用 size_t 作为数据类型。int
默认情况下是有符号的,尽管它的大小也与平台相关,但在大多数现代机器上它将是固定的 32 位(尽管size_t
在任何机器上都是 64 位) 64 位架构,int
在相同的 64 位架构上仍为 32 位长)。总结:使用
size_t
表示对象的大小,其他情况使用int
(或long
)。 请注意,size_t
是无符号的,而int
和long
默认情况下都是有符号的(除非前面加上unsigned
,或者修改为uint
或ulong
)。size_t
1) is the data type used to represent sizes (as its name implies) and 2) is platform (and even potentially implementation) dependent, so it should be used only for representing sizes.Representing a size,
size_t
is naturally unsigned (can you have a box that is negative 3 meters wide?). Manystdlib
functions, includingmalloc
,sizeof
, and various string operation functions usesize_t
as a datatype.An
int
is signed by default, and even though its size is also platform dependent, it will be a fixed 32bits on most modern machine (and thoughsize_t
is 64 bits on any 64-bit architecture,int
remains 32 bits long on those same 64-bit architectures).Summary: Use
size_t
to represent the size of an object andint
(orlong
) in other cases. Be aware thatsize_t
is unsigned while bothint
andlong
are signed by default (unless prepended withunsigned
, or modified touint
orulong
).size_t
类型被定义为sizeof
运算符的无符号整数类型。 在现实世界中,您经常会看到int
定义为 32 位(为了向后兼容),但size_t
定义为 64 位(因此您可以声明超过 4 位的数组和结构体) GiB 大小)在 64 位平台上。 如果long int
也是 64 位,则称为 LP64 约定; 如果long int
是 32 位,但long long int
和指针是 64 位,那就是 LLP64。 您也可能得到相反的结果,即使用 64 位指令来提高速度,但使用 32 位指针来节省内存的程序。 此外,int
是有符号的,size_t
是无符号的。历史上有许多其他平台的地址比
int
的本机大小更宽或更短。 事实上,在 70 年代和 80 年代初,这种情况比不常见:所有流行的 8 位微型计算机都有 8 位寄存器和 16 位地址,16 和 32 位之间的过渡也产生了许多机器地址比寄存器宽。 我偶尔还会在这里看到有关 Borland Turbo C for MS-DOS 的问题,其巨大内存模式在 16 位 CPU 上以 32 位存储 20 位地址(但可以支持 80386 的 32 位指令集); Motorola 68000 有一个 16 位 ALU,带有 32 位寄存器和地址; IBM 大型机有 15 位、24 位或 31 位地址。 您还在嵌入式系统中看到不同的 ALU 和地址总线大小。任何时候
int
小于size_t
,并且您尝试将非常大的文件或对象的大小或偏移量存储在unsigned int
中,它有可能溢出并导致错误。 对于int
,也有可能得到负数。 如果int
或unsigned int
更宽,程序将正确运行,但会浪费内存。如果您想要可移植性,通常应该使用正确的类型来达到目的。 很多人会建议您使用有符号数学而不是无符号数学(以避免像
1U <-3
这样讨厌的、微妙的错误)。 为此,标准库将
中的ptrdiff_t
定义为指针减去另一个指针的结果的有符号类型。也就是说,解决方法可能是根据
INT_MAX
以及0
或INT_MIN
酌情对所有地址和偏移量进行边界检查,然后打开关于比较有符号和无符号数量的编译器警告,以防您错过任何内容。 无论如何,你应该始终、始终、始终检查 C 语言中的数组访问是否溢出。The
size_t
type is defined as the unsigned integral type of thesizeof
operator. In the real world, you will often seeint
defined as 32 bits (for backward compatibility) butsize_t
defined as 64 bits (so you can declare arrays and structures more than 4 GiB in size) on 64-bit platforms. If along int
is also 64-bits, this is called the LP64 convention; iflong int
is 32 bits butlong long int
and pointers are 64 bits, that’s LLP64. You also might get the reverse, a program that uses 64-bit instructions for speed, but 32-bit pointers to save memory. Also,int
is signed andsize_t
is unsigned.There were historically a number of other platforms where addresses were wider or shorter than the native size of
int
. In fact, in the ’70s and early ’80s, this was more common than not: all the popular 8-bit microcomputers had 8-bit registers and 16-bit addresses, and the transition between 16 and 32 bits also produced many machines that had addresses wider than their registers. I occasionally still see questions here about Borland Turbo C for MS-DOS, whose Huge memory mode had 20-bit addresses stored in 32 bits on a 16-bit CPU (but which could support the 32-bit instruction set of the 80386); the Motorola 68000 had a 16-bit ALU with 32-bit registers and addresses; there were IBM mainframes with 15-bit, 24-bit or 31-bit addresses. You also still see different ALU and address-bus sizes in embedded systems.Any time
int
is smaller thansize_t
, and you try to store the size or offset of a very large file or object in anunsigned int
, there is the possibility that it could overflow and cause a bug. With anint
, there is also the possibility of getting a negative number. If anint
orunsigned int
is wider, the program will run correctly but waste memory.You should generally use the correct type for the purpose if you want portability. A lot of people will recommend that you use signed math instead of unsigned (to avoid nasty, subtle bugs like
1U < -3
). For that purpose, the standard library definesptrdiff_t
in<stddef.h>
as the signed type of the result of subtracting a pointer from another.That said, a workaround might be to bounds-check all addresses and offsets against
INT_MAX
and either0
orINT_MIN
as appropriate, and turn on the compiler warnings about comparing signed and unsigned quantities in case you miss any. You should always, always, always be checking your array accesses for overflow in C anyway.这是因为 size_t 可以是 int 以外的任何东西(也许是结构体)。 这个想法是它将它的工作与底层类型分离。
It's because size_t can be anything other than an int (maybe a struct). The idea is that it decouples it's job from the underlying type.
SIZE_T
的定义位于:https://msdn.microsoft.com/en-us/library/cc441980。 aspx 和 https://msdn.microsoft.com/en- us/library/cc230394.aspx
在此处粘贴所需的信息:
SIZE_T
是一个ULONG_PTR
,表示最大字节数指针可以指向。该类型声明如下:
ULONG_PTR
是用于指针精度的无符号长类型。 当将指针转换为长类型以执行指针算术时,使用它。该类型声明如下:
The definition of
SIZE_T
is found at:https://msdn.microsoft.com/en-us/library/cc441980.aspx and https://msdn.microsoft.com/en-us/library/cc230394.aspx
Pasting here the required information:
SIZE_T
is aULONG_PTR
representing the maximum number of bytes to which a pointer can point.This type is declared as follows:
A
ULONG_PTR
is an unsigned long type used for pointer precision. It is used when casting a pointer to a long type to perform pointer arithmetic.This type is declared as follows: