size_t和内存分配

size_t and memory allocation

本文关键字:内存 分配 size      更新时间:2023-10-16

有这样的 std::size_t。它可用于描述对象的大小,因为它可以保证能够表达任何对象的最大大小(因此在此处写)。但是,这是什么意思?实际上,我们在内存中没有对象。因此,这是否意味着这种类型可以存储一个代表我们理论上可以使用最大内存的整数?

如果我尝试写

之类的东西
size_t maxSize = std::numeric_limits<std::size_t>::max();
new char[maxSize];

我会遇到错误,因为数组的总大小限于0x7fffffff。为什么?此外,如果我传递了等于maxSize的非恒定表达式,则将抛出std::bad_array_new_length。如果我通过一个小于maxSize但仍然大于0x7FFFFFFF的表达式,则将抛出std::bad_alloc。我想std::bad_alloc是由于缺乏内存而投掷的,而不是因为大小大于0x7ffffffff。为什么会这样?我想扔 special 例外,如果内存的大小,我们要分配的内容大于0x7ffffffff(这是传递给const的最大值编译时新[])。为什么只有通过maxSize才能抛出std::bad_array_new_length?这种情况特别吗?

顺便说一句,如果我将最大化传递给向量的构造函数:

vector<char> vec(maxSize);

std::bad_alloc将被抛出,而不是std::bad_array_new_length。这是否意味着向量使用不同的分配器?

我正在尝试自己实现阵列。使用未签名的INT来存储大小,容量和指数是一种不好的方法。因此,定义这样的别名是一个好主意:

typedef std::size_t size_type;

并使用size_type代替unsigned int

答案在于创建动态存储持续时间的对象的过程中。

简短,当程序执行A new Expression 为: new char[size]

  1. 它检查s=size*sizeof(char)+x是否是有效的大小(实现定义的0x7ffffffff,取决于ABI)(如果您创建了琐碎的可破坏性类型的数组,则大多数平台上的x = 0)。如果大小无效,则会抛出bad_array_new_lenght,否则,

  2. 它调用分配函数::operator new(s)。此函数的第一个参数是std::size_t,这就是为什么std::size_t必须足够大才能创建任何大小的对象(数组是对象)。

  3. 此分配功能要求系统保留大小s的存储区域。如果系统成功保留此空间,它将返回一个指针到存储区域的开头。否则,它称为新处理程序和重试分配,但是如果再次失败,它将抛出bad_alloc

  4. 如果分配成功,则默认初始化(在这种情况下)size char(no-op)在分配的存储中,它也可能存储此数组的大小分配的存储(原因是添加的x)(在执行A delete表达式时使用这是为了知道必须如何调用许多破坏者的方式。如果驱动器很琐碎,这不是必需的))。

您将在C 标准中找到所有详细信息(第6.7.4条[BASIC.STC.DYNAMIC],§8.3[EXPR.NEW],§8.4[EXPR.DELETE],§21.6[support.dynamic])。

对于最后一个问题,您可以考虑使用签名的类型用于索引和对象大小。即使对象大小或索引不应该为负,该标准也强加了未签名的算术遵循的模量算术,从而限制了严重优化。此外,未签名的整数类型算术和比较是错误的经常受试者。std::size_t出于兼容原因未签名,因为史前机器的碎屑短!(16位或更少!)