4

这对于 C++ 非菜鸟来说可能是显而易见的,但这让我有点难过——一个类的字符串成员是否在该类中分配了可变数量的空间?或者它只是在内部分配一个指向内存中其他空间的指针?例如在这个例子中:

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

class Child {
    public:
    string Name;
}

如果我创建一个“new Parent()”并添加一些具有不同长度字符串的子级,它是如何在堆上分配的?是 Parent 4 字节,Child 4 字节(或任何指针大小,加上固定大小的内部数据),然后是堆上其他地方的随机一堆字符串?还是全部捆绑在内存中?

我猜一般来说,容器类型本身总是固定大小的,并且只包含指向其可变大小数据的指针,并且这些数据总是在堆上吗?

4

4 回答 4

7

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

C++ 2011 标准彻底定义了分配器,以支持将分配机制传递给对象及其所有子对象。当然,类也需要支持这种机制。如果您的ParentChild类有合适的构造函数采用分配器并将此分配器传递给所有进行分配的成员,它将通过系统传播。这样,可以将属于一起的对象的分配安排得相当接近。

于 2013-01-03T23:11:14.590 回答
3

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

*因为string这并不完全正确。通常使用一种称为短字符串优化的优化技术。在这种情况下,小字符串被嵌入到对象内部(否则将存储指向堆数据的指针的位置),并且仅当字符串太长时才分配堆内存。

于 2013-01-03T23:11:45.030 回答
1

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

如果我们有vector<int> vi;,则 的大小vi始终是固定的,sizeof(vector<int>)确切地说,与 中的int's的数量无关vi

于 2013-01-03T23:10:46.280 回答
0

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

不,不是的。

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

不,不是的。

一个std::string分配wahteversizeof(std::string)是。

不要混淆

  1. 物体的大小
  2. 对象负责的资源的大小。
于 2013-01-03T23:10:27.433 回答