c++字符串/容器分配

C++ string / container allocation

本文关键字:分配 字符串 c++      更新时间:2023-10-16

对于不熟悉c++的人来说,这可能是显而易见的,但它让我有点困惑——类的字符串成员是否在该类中分配了可变数量的空间?或者它只是在内部分配一个指针到内存中的其他空间?例如:

class Parent {
    public:
    vector<Child> Children;
}
class Child {
    public:
    string Name;
}

如果我创建一个"new Parent()"并添加一些具有不同长度字符串的孩子,如何在堆上分配?父级是4个字节,子级是4个字节(或者无论指针大小,加上固定大小的内部数据),然后是堆上其他地方的随机字符串堆?还是在记忆中捆绑在一起?

我猜在一般情况下,容器类型总是固定大小的自己,只是包含指针到他们的可变大小的数据,数据总是在堆上吗?

c++中的类总是固定大小的。当存在可变大小的组件时,例如向量的元素或字符串中的字符,它们可以在堆上分配(对于小字符串,它们也可以嵌入到字符串本身中;这被称为小字符串优化()。也就是说,您的Parent对象将包含std::vector<Child>,其中Child对象在堆上分配(std::vector<...>对象本身可能保留三个单词的数据,但有几种方式可以布局)。Child中的std::string对象分配自己的内存。也就是说,可能会有相当多的内存分配。

c++ 2011标准彻底定义了分配器,以支持向对象及其所有子对象传递分配机制。当然,类也需要支持这种机制。如果您的ParentChild类具有接受分配器的合适构造函数,并将该分配器传递给执行分配的所有成员,则该分配器将通过系统传播。通过这种方式,可以将属于一起的对象分配到相当接近的位置。

c++中的类总是有固定的大小。因此vectorstring只能包含指向堆分配内存*的指针(尽管它们通常包含比一个指针更多的数据,因为它也需要存储长度)。因此,对象本身总是有一个固定的长度。

*对于string,这并不完全正确。通常使用一种称为短字符串优化的优化技术。在这种情况下,小字符串被嵌入到对象中(在指向堆数据的指针存储的地方),堆内存只在字符串太长时才分配。

是的——用你的话来说——容器类型本身总是固定大小的,并且只包含指向其可变大小数据的指针。

如果我们有vector<int> vi;, vi的大小总是固定的,确切地说,sizeof(vector<int>)的大小是固定的,无论viint的数量如何

类的字符串成员是否在该类中分配可变数量的空间?

不,它没有。

或者它只是在内部分配一个指针到内存中的其他空间?

不,它没有。

一个std::string分配任何sizeof(std::string)

不要混淆

  1. 对象的大小
  2. 对象所负责的资源的大小。