"Largest possible object" size_t解释

"Largest possible object" on size_t explanations

本文关键字:解释 object Largest possible size      更新时间:2023-10-16

我知道这里有一个类似的问题,但我不清楚。我刚开始学习C++,偶然发现了size_t。我已经读过它,我想我理解它的目的,但在大多数解释中,他们使用短语"您的系统可以处理的最大可能对象"。

当他们说反对时,他们是什么意思?我知道的对象是从类实例化的对象,但我可以在该对象上添加很多属性,所以我认为这不是他们所引用的对象类型。

术语对象的标准含义并不特定于类。该术语起源于C语言,其含义在C++没有太大变化。术语"对象"是术语"变量"(任何变量)的松散同义词。您声明的每个变量都是一个对象。以下所有对象

int a;                // an object of type 'int'
double b;             // an object of type 'double'
char s[1024];         // an object of type 'char [1024]'
SomeClass x;          // an object of type 'SomeClass'
SomeOtherClass y[10]; // an object of type 'SomeOtherClass [10]'

换句话说,对象是存储在内存中的数据片段,而不是由代码组成的函数

类型size_t的规范说,它应该能够存储实现支持的最大对象的大小。通常,创建大型对象的最简单方法是声明一个大型数组。当然,您也可以通过创建足够大的类类型来创建大型对象。

实现支持的最大对象大小通常是该实现的固有属性(这可能也取决于编译器设置)。它被硬编码到实现中。因此,如果size_t足够大以覆盖该范围,则始终足以存储任何对象的大小。

例如,某些实现可能会将最大对象大小限制为 64K 字节。在这样的实现中,size_t可以安全地定义为 16 位无符号整数。此size_t将始终足够大以存储任何对象的大小(任何sizeof的结果),因为该实现永远不会允许您创建更大的对象或声明较大大小的类型。


还有另一种标准类型在某种程度上与最大可能的对象大小有关 -ptrdiff_t.这是一种有符号类型,旨在存储指向同一数组的两个指针之间的差异。如果某些实现允许您创建与最大值size_t一样大的对象(例如 char 数组),那么为了适应此类指针之间的任何差异,ptrdiff_t必须至少比size_t宽 1 位(由于其符号)。也就是说,如果size_t宽度为 16 位,则ptrdiff_t必须至少为 17 位宽。这是一个相当奇怪的情况。

但是,幸运的是(或不幸的是)实现不需要能够在ptrdiff_t中存储两个指针之间的任何差异。这意味着他们有借口定义与size_t宽度相同的ptrdiff_t.

一些实现利用了这个借口:它们定义了相同宽度的size_tptrdiff_t。它们允许您创建与最大值一样大的对象size_t.并且还告诉您在减去远处指针时要小心:结果可能不适合ptrdiff_t,溢出并导致未定义的行为。

其他实现遵循不同的方法:它们还定义了相同宽度的size_tptrdiff_t,但它们人为地将最大对象大小限制为size_t范围的一半。在这样的实现中,指向同一数组的任何两个指针总是可以安全地减去。(但显然,您需要为此付出代价,最大对象大小减少 2 倍)。

它是一种可以容纳您可能分配的最大连续内存块的大小(以字符为单位)的类型。正如您所观察到的,对象由指针等组成,因此对象拥有的实际内存量可能大于size_t可以表示的内存量。但是,sizeof运算符返回的对象的大小(不考虑对象中指针的动态内存分配等因素)必须在size_t中存储。

代码

char array[100000];

必须具有适合size_t的尺寸。当数组接近SIZE_MAX时,编译器通常会出于其他原因拒绝,但SIZE_MAX是一个可靠的限制。

您还会注意到 sizeof(int) 返回一个size_t。但是,此数字可能是 2 或 4,并且不太可能大于 8。因此,虽然size_t旨在允许处理大量数字,但大多数用途是用于小数字。

您还会注意到代码

int *array = malloc(N * sizeof(int));
for(i=0;i<N;i++)
array[i] = 0;

真的应该有 N 和 i 的size_t。这就是size_t的想法开始令人讨厌的地方。数组索引的无符号值使索引难以 操纵。

而C中的"对象"是任何可以识别的,并且占据连续的 内存中的字节数。所以一个结构,或者一个数组,或者一个变量,或者一个结构数组。但不是一个结构加上在它之后声明的整数数组,它恰好占据了下一个内存