使用new创建一个结构数组

Create an array of structure using new

本文关键字:一个 结构 数组 new 创建 使用      更新时间:2023-10-16

我这里有一些困难的情况,我希望有人能帮助我。

我有以下内容,

struct CandyBar{ 
  std::string name; 
  double weight; 
  int calories; 
} ;

现在,创建一个数组结构来包含许多CandyBars是非常简单的,我已经这样做了;

int main(){
   CandyBar bars[] = {{"Mango tart", 2.3, 100}, {"Yo Yo", 3.2, 130}, {"Orange Ball", 1.7, 98}};
  return 0;
}

但是,现在我想用new创建相同的结构。这是相当简单的,当我认为它,但这崩溃,不工作。

CandyBar *bars = new CandyBar;
  (*bars).name = "Mango tart";
   bars->weight =  2.3;
   bars->calories =  100;
   bars += 1;
  (*bars).name = "Yo Yo";
  bars->weight =  3.2;
  bars->calories =  130;
  bars += 1;
  (*bars).name =  "Orange Ball";
  bars->weight =  1.7;
  bars->calories =  98; 

但是,这不起作用。因为我认为第一个指针是指向第一个结构的内存位置,然后我创建结构,然后使用bar += 1增加地址,然后继续创建指针,但我错过了一些非常严重的东西。

我非常感谢你的帮助。

在第二个示例中,您只分配了一个CandyBar结构,但是您将其视为一个数组。这是不会有好结果的,而且会导致缓冲区溢出。

为了分配CandyBars的数组,您需要告诉new您想要一个数组,如下所示:

CandyBar* bars = new CandyBar[3];

确保当你删除CandyBars的数组时,你是这样使用数组删除:

delete[] bars;

总而言之,在c++产品代码中,您通常会使用std::vector或std:: array来处理这种情况,因为您不必像在这种特殊情况下那样处理那么多的资源管理。

如果您必须在堆上动态分配数组并且仍然使用RAII,我还会查看boost::shared_arrayboost::scoped_array.

空间只分配给一个CandyBar,所以您正在写入未分配的堆内存。这是大禁忌。实际上你很幸运,它失败了,因为它有能力产生非常难以调试的问题。

您可以为更多的CandyBar分配空间,如下所示:

CandyBar *bars = new CandyBar[3]; // 3 CandyBars.

…不要忘记使用数组删除器,像这样:

delete[] bars;

但是,仍然有可能超出您已分配的CandyBar的数量。在c++中,更可取的方法是使用std::vector .

在本例中,我为CandyBar提供了一个构造函数,并将它们放入std::vector中。

#include <string>
#include <vector>
struct CandyBar{ 
  std::string name;
  double weight;
  int calories;
  CandyBar(std::string name, double weight, int calories)
  {
      this->name = name;
      this->weight = weight;
      this->calories = calories;
  }
};
int main()
{
    std::vector<CandyBar> bars;
    bars.push_back(CandyBar("Mango tart", 2.3, 100));
    bars.push_back(CandyBar("Yo Yo", 3.2, 130));
    bars.push_back(CandyBar("Orange Ball", 1.7, 98));
    return 0;
}

没有new 's,没有delete 's,没有泄漏,没有腐败。

我还想补充一点,如果你使用的编译器支持一些c++ 11,并且不希望std::vector给你的动态分配,你可以考虑使用std::array代替。

Foo * a = new Foo只为一个Foo实例分配空间。如果你想分配一个Foo的数组,你需要使用Foo * a = new Foo[ARRAY_LEN]


基本上,你真正想做的是动态分配一些内存来保存对象数组,在你的例子中是CandyBar对象。问题是,您使用的是new运算符,它只为一个这样的对象分配内存。然后尝试使用返回的内存地址,就好像它指向一个数组一样。您将不可避免地尝试访问尚未分配的内存,这将导致分段错误(充其量)。

您真正寻找的操作符是new[]操作符(调用为new CandyBar[ARRAY_LEN]),它为指定数量的对象数组分配足够的内存。然后,您可以接受返回的内存地址,并将其完全视为您提供的大小的数组,而不必担心占用内存分配。

一般来说,如果你处理的是一个CandyBar的集合,它在你的程序生命周期中可能会增长或缩小,那么分配一个固定大小的数组并不是最好的方法。看看c++ STL中的std::vector模板类- std::vector<CandyBar>可以根据您想要存储的CandyBar的数量动态增长或收缩,并且可以像数组一样自由访问(例如foo[42])。

你应该分配一个CandyBar数组:

CandyBar *bars = new CandyBar[20];

然后使用bars[0], bars[1]bars[19]等,以访问单个糖果棒。

注意,您的代码bars + 1向指针添加了一个sizeof CandyBar,但这指向一个未分配的区域(因为您刚刚分配了一个CandyBar)。因此你的代码会崩溃。

相关文章: