使用new创建一个结构数组

5 c++ struct data-structures

我有一些困难的情况,我希望有些机构会帮助我.

我有以下,

struct CandyBar{ 
  std::string name; 
  double weight; 
  int calories; 
} ;
Run Code Online (Sandbox Code Playgroud)

现在,为了创建一个包含许多CandyBars的结构数组,我做的很简单;

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

但是,现在我想用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; 
Run Code Online (Sandbox Code Playgroud)

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

我将衷心感谢您的帮助.

Tim*_*sch 14

在第二个示例中,您只分配单个CandyBar结构,但您将其视为数组.这不会很好地结束,并且是缓冲区溢出的配方.

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

CandyBar* bars = new CandyBar[3];
Run Code Online (Sandbox Code Playgroud)

确保在删除数组时CandyBars,使用数组删除如下:

delete[] bars;
Run Code Online (Sandbox Code Playgroud)

总而言之,在C++生产代码中,您通常会使用std :: vector或std :: arrray来处理这种情况,因为在这种情况下您不必处理尽可能多的资源管理.

如果你必须在堆上动态分配一个数组并仍然使用RAII,我也会看看boost::shared_arrayboost::scoped_array.


Sea*_*ine 6

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

你可以为更多CandyBar的东西分配空间:

CandyBar *bars = new CandyBar[3]; // 3 CandyBars.
Run Code Online (Sandbox Code Playgroud)

...并且不要忘记使用像这样的数组deletor:

delete[] bars;
Run Code Online (Sandbox Code Playgroud)

但是,仍然有能力超出CandyBar你分配的数量.在C++中这样做的首选方法是使用a 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;
}
Run Code Online (Sandbox Code Playgroud)

new,没有delete,没有泄漏,没有腐败.

我还要补充一点,如果您使用的是具有某些C++ 11支持的编译器,并且不希望动态分配std::vector给您,您可以考虑使用std::array.