【问题标题】:How to fill array of struct containing pointer arrays如何填充包含指针数组的结构数组
【发布时间】:2018-06-13 17:24:44
【问题描述】:

我在 C++ 中有一个小而非常简单的问题。我想填充包含双数组的结构数组。我怎样才能做到这一点?

typedef struct 
{
    double *inputs[2];
    double *target[1];
} Data;

Data data[] 
{
    new double[2]{10, 20}, new double[1]{30},
    new double[2]{40, 50}, new double[1]{60},
    new double[2]{70, 80}, new double[1]{90},
    new double[2]{100, 110}, new double[1]{120} 
};

main()

printf("data[0]: inputs: %f %f, targets: %f\n",
                   *data[0].inputs[0],
                   *data[0].inputs[1],
                   *data[0].target[0]);

这是我的想法,但是当我运行它时,它会打印:

data[0]: inputs: 10.000000 30.000000, targets: 40.000000

当然,在数组数据的末尾(如第 3 或第 4 项)会导致UNAUTHORIZED ACCESS TO MEMORY

感谢您的想法和耐心;)

【问题讨论】:

  • 这段代码中有很多内容。你为什么new一切?为什么使用大小为 1 的数组?为什么在 C++ 中使用printf?你为什么typedef你的struct?看来您可能正在混合使用 c 和 c++ 教程。学习 c++ 时避免使用 c 教程。
  • 停止使用这么多指针和new现在。使用std::vector。 C++ 不是 C。
  • This 和你写的差不多,格式化后更容易看到 data 是如何初始化的。每个Data 有三个news。

标签: c++ arrays pointers data-structures struct


【解决方案1】:

使用现代 c++ 使您的代码更简单、更安全:

#include <iostream>
#include <array>
#include <vector>

struct Data {
    std::array<double,2> inputs;
    std::array<double,1> target;
};

int main()
{
    std::vector<Data> data = {
        { {10, 20}, {30} },
        { {40, 50}, {60} },
        { {70, 80}, {90} },
        { {100, 110}, {120} }
    };
    std::cout << "data[0]: inputs: " << data[0].inputs[0] << " " << data[0].inputs[1] << ", targets: " << data[0].target[0] << "\n";
}

您最初的问题是 double *inputs[2] 声明了一个指向 double 的 2 元素数组,而不是指向 doubles 的 2 元素数组的指针。

【讨论】:

    【解决方案2】:

    您的 Data 结构包含 2 个字段、2 个 double 指针的数组和 1 个 double 指针的数组。

    这意味着初始化它最多需要3个double指针,这意味着在你的初始化中真的看起来像这样

    Data data[]{
    {new double[2]{ 10, 20 },   new double[1]{ 30 },        new double[2]{ 40, 50 }}, //1st object
    {new double[1]{ 60 },       new double[2]{ 70, 80 },    new double[1]{ 90 }}, //2nd object
    {new double[2]{ 100, 110 }, new double[1]{ 120 }} //3rd object but 2 parameters??
    };
    

    尝试循环打印时,第 3 个对象会导致段错误,因为 target 字段没有正确初始化(使用 Visual Studio 调试时它设置为 null,不确定其他编译器)。

    【讨论】:

    • 聚合初始化未列出的字段是值初始化的,这对于指针确实意味着它们被设置为nullptr
    【解决方案3】:

    你的问题在这里:

    typedef struct {
        double *inputs[2];  // this
        double *target[1];  // this
    } Data;
    

    这是一个指针数组,并希望它的行为是动态的一维数组。 简单的解决方法是:

    struct Data {
        double *inputs = nullptr;
        double *target = nullptr;
    } ;
    

    但是,您使用new 分配了大量的堆内存,这使delete 的任务变得乏味,从而使您的数据结构的管理变得非常困难。 我强烈建议您使用std::vector&lt;&gt;,这会使您的任务更轻松、更干净。

    #include <vector>
    #include <iostream>
    
    struct Data
    {
       std::vector<double> inputs; // use  instead of double *inputs[2];
       std::vector<double> target; // use  instead of double *target[1];
       //Data(const std::vector<double>& a, const std::vector<double>& b) :inputs(a), target(b){}
    };
    
    int main()
    {
       std::vector<Data> data = // now in your main structure array
       {  { {10, 20}, {30} },
          { {40, 50}, {60} },
          { {70, 80}, {90} },
          { {100, 110},{120} }
       };
       // access using range based loop now
       for(const Data& each_strcut: data)
          std::cout << each_strcut.inputs[0] << " " << each_strcut.inputs[1]
                    <<"\t" << each_strcut.target[0] << std::endl;
       return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-11-03
      • 2013-09-02
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      • 2017-07-27
      • 1970-01-01
      • 1970-01-01
      • 2019-04-14
      相关资源
      最近更新 更多