std::vector 连续部分的 C++ 大小

C++ Size of std::vector Contiguous Section

在一个结构中,为了最小化填充,应该声明从大到小的元素,对吗?

std::vector 在不一定连续的部分上分配内存,对吗?

在一个结构中,考虑 std::vector 在结构中的填充位置时,我应该考虑多少位?

Within a struct, to minimize padding, one should declare the elements largest to smallest, correct?

这取决于。在某些情况下,您可能正在优化缓存行为,而这不一定会导致该排序。在大多数实现中,以这种方式排序的东西将导致结构的最小尺寸(填充最少),但标准或类似的东西不能保证这一点。1

An std::vector allocates memory on a section that is not necessarily contiguous, correct?

这是不正确的。 vector 需要使用一个连续的部分。见 N3936 23.3.6.1/1:

A vector is a sequence container that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().

Within a struct, how many bits should I consider the std::vector to be when considering its placement within the struct with respect to padding?

Vector 看不到有关结构中成员的任何信息;它只知道大小。


1考虑一个假设的机器,它有 4 个字节 ints 并且要求所有内容都是 5 字节对齐的。 (我不知道有这样的机器,但标准是以这样的方式编写的,这样的机器是可能的)在那种情况下,结构如下:

struct X
{
    int a;
    int b;
    char c;
    char d;
};

会浪费 space 因为

struct X
{
    int a;
    char c;
    int b;
    char d;
};

会将每个 char 存储到未使用的第 5 字节中。这就是标准定义此实现的原因。

我假设您正在想象这样的事情:

struct foo {
  // ...
  std::vector<T> vec;
  // ...
};

我认为您缺少的是 std::vector 对象本身和它为其元素分配的内存之间的区别。 std::vector 本身占用 sizeof(std::vector) 字节,因此如果您考虑填充,将至少贡献这么多字节到它包含在其中的结构。

在内部,std::vector 对象在存储元素的其他地方分配一个连续的内存区域。为了允许增加或减少大小,std::vector 可以在您添加或删除元素时分配不同大小的内存。但是,这与您的问题无关,因为此内存不会影响 std::vector 的大小,因此不会影响它所属的结构的大小。