C++ 中 size_t 和 int 有什么区别?

发布于 2024-07-13 10:36:24 字数 117 浏览 8 评论 0原文

在几个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱情眠于流年 2024-07-20 10:36:25

来自友好的维基百科

stdlib.h 和 stddef.h 头文件定义了一个名为 size_t 的数据类型,用于表示对象的大小。 接受大小的库函数期望它们的类型为 size_t,并且 sizeof 运算符的计算结果为 size_t。

size_t 的实际类型与平台相关; 一个常见的错误是假设 size_t 与 unsigned int 相同,这可能会导致编程错误,尤其是在 64 位架构变得更加流行的情况下。

另外,请检查为什么 size_t 很重要

From the friendly Wikipedia:

The stdlib.h and stddef.h header files define a datatype called size_t which is used to represent the size of an object. Library functions that take sizes expect them to be of type size_t, and the sizeof operator evaluates to size_t.

The actual type of size_t is platform-dependent; a common mistake is to assume size_t is the same as unsigned int, which can lead to programming errors, particularly as 64-bit architectures become more prevalent.

Also, check Why size_t matters

他是夢罘是命 2024-07-20 10:36:25

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 是无符号的,而 intlong 默认情况下都是有符号的(除非前面加上 unsigned,或者修改为uintulong)。

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?). Many stdlib functions, including malloc, sizeof, and various string operation functions use size_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 though size_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 and int (or long) in other cases. Be aware that size_t is unsigned while both int and long are signed by default (unless prepended with unsigned, or modified to uint or ulong).

鸠书 2024-07-20 10:36:25

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,也有可能得到负数。 如果 intunsigned int 更宽,程序将正确运行,但会浪费内存。

如果您想要可移植性,通常应该使用正确的类型来达到目的。 很多人会建议您使用有符号数学而不是无符号数学(以避免像 1U <-3 这样讨厌的、微妙的错误)。 为此,标准库将 中的 ptrdiff_t 定义为指针减去另一个指针的结果的有符号类型。

也就是说,解决方法可能是根据 INT_MAX 以及 0INT_MIN 酌情对所有地址和偏移量进行边界检查,然后打开关于比较有符号和无符号数量的编译器警告,以防您错过任何内容。 无论如何,你应该始终、始终、始终检查 C 语言中的数组访问是否溢出。

The size_t type is defined as the unsigned integral type of the sizeof operator. In the real world, you will often see int defined as 32 bits (for backward compatibility) but size_t defined as 64 bits (so you can declare arrays and structures more than 4 GiB in size) on 64-bit platforms. If a long int is also 64-bits, this is called the LP64 convention; if long int is 32 bits but long 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 and size_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 than size_t, and you try to store the size or offset of a very large file or object in an unsigned int, there is the possibility that it could overflow and cause a bug. With an int, there is also the possibility of getting a negative number. If an int or unsigned 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 defines ptrdiff_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 either 0 or INT_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.

复古式 2024-07-20 10:36:25

这是因为 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.

八巷 2024-07-20 10:36:25

SIZE_T 的定义位于:
https://msdn.microsoft.com/en-us/library/cc441980。 aspxhttps://msdn.microsoft.com/en- us/library/cc230394.aspx

在此处粘贴所需的信息:

SIZE_T 是一个 ULONG_PTR,表示最大字节数指针可以指向。

该类型声明如下:

typedef ULONG_PTR SIZE_T;

ULONG_PTR 是用于指针精度的无符号长类型。 当将指针转换为长类型以执行指针算术时,使用它。

该类型声明如下:

typedef unsigned __int3264 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 a ULONG_PTR representing the maximum number of bytes to which a pointer can point.

This type is declared as follows:

typedef ULONG_PTR SIZE_T;

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:

typedef unsigned __int3264 ULONG_PTR;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文