具有灵活大小结构的新数组分配?

时间:2019-01-08 21:02:17

标签: c++

我正在阅读有关具有灵活数组成员的结构的信息,并且编写了一个小程序来测试我的理解:

struct HelloWorld {
    int a;
    std::string b;
};

std::string arr[5] = { "abcdetttttttttttttttttttttttttt", 
                       "abcdefgh", "abcrrrr", "abcdtttttttt",
                       "abcdezzzzzzzz" };
HelloWorld * h = new HelloWorld[5];
for (int i = 0; i < 5; i++) {
    std::cout << (h+i) << std::endl;
    h[i].a = 5;
    h[i].b = arr[i];
}
for (int i = 0; i < 5; i++) {
  std::cout << (h + i) << std::endl;
}

首先,我了解到在使用sizeof时,可变数组成员(在这种情况下为字符串b)不计入结构的大小。但是,当我计算sizeof HelloWorld时,它将返回48个字节。不应该只是4个字节吗?其次,当我动态分配一个由5个HelloWorld组成的数组时,每个对象的地址被48个字节分隔。即使当我用不同大小的字符串填充成员b时,这些地址也不会更改,因此我猜测该结构会将字符串存储在其他位置,而不是通过“ new”存储在分配的空间中。这些字符串存储在哪里?

1 个答案:

答案 0 :(得分:4)

似乎您正在混合使用两种不同的语言C和C ++,并且正在尝试使用C语言中C语言中可用的灵活数组成员的概念,而该概念根本不存在。

摘自cppreference.com的C语言中灵活数组成员的简短示例,但略有缩短:

  

如果一个结构定义了至少一个命名成员,则允许   另外声明其最后一个成员的数组类型不完整...

struct s { int n; double d[]; }; // s.d is a flexible array member 
struct s *s1 = malloc(sizeof (struct s) + 64); // as if d was double d[8]
s1->d[0] = 1.0;
s1->d[1] = 2.0;

因此,使用灵活的数组成员,您可以根据需要单独创建较小或较大的struct s对象,同时仍然可以使用符号s.d[x]访问该数组的成员。

相比之下,在C ++语言中,类似struct s { int n; double d[]; }的定义是非法的,因为C ++不支持灵活的数组成员。 在C ++中,您将通过使用动态集合数据类型作为成员来解决此类问题:

struct s {
   int n;
   std::vector<double> d;
} s1;
...
s1.d.push_back(1.0);
s1.d.push_back(2.0);
s1.d[0] += 10;