【问题标题】:C++ string / container allocationC++ 字符串/容器分配
【发布时间】:2013-01-03 23:04:50
【问题描述】:

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

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

class Child {
    public:
    string Name;
}

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

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

【问题讨论】:

  • 您的最后一点是考虑它的最佳方式,而不涉及他们采用的可选分配器。
  • @chris Cool,谢谢 - 是的,还没有必要使用自定义分配器。
  • 如果您使用的是 VS2010 或 VS2012,您可以通过将以下编译器开关添加到项目的附加命令行选项 /d1reportSingleClassLayoutxxx 来了解自己(其中 xxx 是用作与类匹配的子字符串的字符串报告)。感谢 AltDevBlogADay 的 Alex Darby,他指出了这个无证转换。还有另一个未记录的编译器选项,称为 /d1reportAllClassLayout,但它列出了所有类。

标签: c++ string stl


【解决方案1】:

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

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

【讨论】:

  • 谢谢 - (也感谢@Grizzly),C++ 类总是固定大小的事实消除了我对内存使用的很多困惑。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    如果我们有vector&lt;int&gt; vi;,则vi 的大小始终是固定的,确切地说是sizeof(vector&lt;int&gt;),与viint 的数量无关。

    【讨论】:

      【解决方案4】:

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

      不,它没有。

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

      不,它没有。

      std::string 分配 wahtever sizeof(std::string) 是。

      不要混淆

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

      【讨论】:

      • 实际的字符数据必须去某个地方,对吧?所以听起来 sizeof(std::string) 是固定大小的位,然后可变大小的字符串数据在内存中的其他地方。
      • 是的,当然。但它肯定不在课堂上。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      • 2015-09-15
      • 1970-01-01
      • 2012-04-03
      相关资源
      最近更新 更多