首页 文章

带字符串的结构的C内存分配

提问于
浏览
1

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

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

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

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";

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

2 回答

  • 0

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

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

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

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

  • 0

    你的车库只有引用,所以你的阵列可以在堆栈上分配没有问题 . 但是,在内部,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 .

相关问题