【问题标题】:C++ Memory Allocation for Struct With String带字符串的结构的 C++ 内存分配
【发布时间】:2014-11-13 01:06:47
【问题描述】:

如果我在结构中有一个字符串成员,然后将其存储到数组中,那么内存是如何分配的?

struct garage {
   int ncars;
   int nspaces;
   int nmechanics;
   string name;
}

但是对于最后一个成员 name,string 基本上是 basic_string 的 typedef,所以它的内存在定义时就被分配了,对吧?例如:garage.name = "酷车"; 但是,如果我还没有定义该成员,并将结构存储在一个数组中:

garage nearby_garages[15];
garage g0, g1, g2;

nearby_garages[0] = g0; nearby_garages[1] = g1; nearby_garages[2] = g2;

garage current;
current = nearby_garage[1];
current.name = "Jack's Garage";

字符串大小可以根据字符串/数据的长度而变化。结构大小可以根据字符串大小而变化,这意味着数组大小可以根据结构大小而变化,但是如果预先分配了数组,它就会分崩离析。我可以看到这个工作的唯一方法是如果字符串是指向未夹在结构中的内存位置的指针。但我不认为这就是这里发生的事情。请帮忙?

【问题讨论】:

    标签: c++ string memory struct allocation


    【解决方案1】:

    您的车库只有引用,因此您的数组可以毫无问题地分配到堆栈上。然而,在内部,std::string 执行 new/malloc 为您的数据创建内存。

    然后,您的车库会保存对字符串的引用,该字符串包含指向包含您的数据的内存块的指针。这里没有任何问题,因为车库在创建时就知道字符串将有一个指向数据的指针,所以指针已经有一个空间。

    当您包含诸如“Jack's Garage”之类的文字时,编译器会创建一个特殊的位置来保存这些字符串,它们不会分配在同一个内存段中。

    最后,当您调用 current.name = "Jack's Garage" 时,C++ 将确定它需要在 const char* 到 std::string 之间进行转换。对我们所有人来说幸运的是,存在这样的转换。然后您的作业将转换为

    current.name = std::string("Jack's Garage");
    

    然后std::string的赋值运算符会将值复制到current.name。新内存将在车库内分配以保存该值,并且(可能)该 memcpy 将在较低级别调用。

    【讨论】:

      【解决方案2】:

      std::string 在实现上类似于std::vector:本质上是一个指针和大小,两个指针(开始和结束),或者一个指针和查询分配器块大小的能力。

      在某些情况下,它还可以实现 SSO(小字符串优化),其中字符串结构本身有一个用于短字符串的小缓冲区,并切换到使用指针来处理较长的字符串。

      如果没有 SSO,std::string 拥有的字符的后备存储在构造或赋值时分配为文字(或使用另一个字符串,如果实现不是 COW),或在连接期间重新分配。

      在您上面的代码中,current.name = "Jack's Garage" 将是分配站点(在这种情况下没有 SSO)。

      【讨论】:

      • 狡猾而聪明。谢谢!
      猜你喜欢
      • 2021-11-30
      • 1970-01-01
      • 2021-11-20
      • 2023-04-02
      • 2018-08-05
      • 2011-12-06
      • 1970-01-01
      • 2022-11-28
      • 2021-08-31
      相关资源
      最近更新 更多