【问题标题】:struct members gets cleared when accessed结构成员在访问时被清除
【发布时间】:2020-06-07 19:54:36
【问题描述】:

首先,如果我的解释不好,我想道歉,英语不是我的第一语言。如果您不理解我在这里写的内容,我很乐意尝试更好地解释。

我正在尝试解决this problem。我有一个结构数组(车间),它是另一个结构(Available_Workshops)的成员。我的问题是,数组中 Workshop 结构的所有实例的所有数据成员在 CalculateMaxWorkshops 函数中的 for 循环的第一次迭代后被清除,从而导致第一次循环后出现分段错误。我尝试使用向量和动态数组,但问题仍然存在。

这是我的代码。

#include <iostream>
using namespace std;

struct Workshop
{
    int start = 0;
    int dur = 0;
    int end = 0;
};

struct Available_Workshops
{
    int n = 0;
    Workshop *arr = new Workshop[n];
};

Available_Workshops* initialize(int s[], int d[], int n)
{
    Available_Workshops aw;
    Available_Workshops *u;
    aw.n = n;
    for (int i = 0 ; i < n ; i++)
    {
        Workshop w;
        w.start = s[i];
        w.dur = d[i];
        w.end = w.start + w.end;
        cout << w.end;
        aw.arr[i] = w;
    }
    u = &aw;
    return u;
};

int CalculateMaxWorkshops(Available_Workshops *time_table)
{
    int n = time_table-> n, //number of workshop objects
    int current_class, next_class=0;
    int max_classes = 0;
    for (int i = 0 ; i < n-1 ; i++)
    {
        Workshop cur = time_table -> arr[i];
        current_class = cur.end; //all struct members gets cleared for some reason after this line
    }
}

我只能编辑上面的,下面的代码被锁定在站点编辑器中。

int main() {
    int n; // number of workshops
    cin >> n;
    // create arrays of unknown size n
    int* start_time = new int[n];
    int* duration = new int[n];

    for(int i=0; i < n; i++){
        cin >> start_time[i];
    }
    for(int i = 0; i < n; i++){
        cin >> duration[i];
    }

    Available_Workshops * ptr;
    ptr = initialize(start_time,duration, n);
    cout << CalculateMaxWorkshops(ptr) << endl;
    return 0;
}

我在 CalculateMaxWorkshops 函数中尝试了不同的方法,但它导致了不同的问题。

int CalculateMaxWorkshops(Available_Workshops *time_table)
{
    int n = time_table -> n, //number of workshop objects
    int current_class, next_class=0;
    int max_classes = 0;
    for (int i = 0 ; i < n-1 ; i++)
    {
        Workshop *cur = &(time_table -> arr[i]);
        current_class = cur -> end;
    }
}

这次的问题是数组向后“偏移”。换句话说,存储在 arr[i] 中的数据被存储在 arr[i-1] 中,并且在 arr[n-i-1] 中的数据被重新初始化。

总而言之,第一个问题是数据变为 NULL,而第二个问题是数据向后偏移并重新初始化,例如 start = -17891602

【问题讨论】:

    标签: c++ arrays struct


    【解决方案1】:

    在此函数中,您将返回一个存储局部变量地址的指针:

    Available_Workshops* initialize(int s[], int d[], int n)
    {
        Available_Workshops aw;
        Available_Workshops *u;
        // ...
        u = &aw;
        return u;
    };
    

    取消引用此函数返回的指针会调用未定义的行为。

    你需要为这个指针分配内存:

    Available_Workshops* initialize(int s[], int d[], int n)
    {
        Available_Workshops aw;
        Available_Workshops *u;
        // ...
        u = new Available_Workshops{aw};
        return u;
    };
    

    以后记得delete这个内存。

    一般来说,我建议使用std::unique_ptr,或者最好完全避免使用指针。但是,由于您无法更改 main,因此您无法选择。

    【讨论】:

      【解决方案2】:

      除了cigien指出的问题,你这里还有一个问题

      struct Available_Workshops
      {
           int n = 0;
           Workshop *arr = new Workshop[n];
      };
      

      arr 是一个指向零长度数组的指针(因为n 为零)。但是这里

      for (int i = 0 ; i < n ; i++)
      {
          ...
          aw.arr[i] = w;
      }
      

      您将其视为具有长度n

      您需要为足够的研讨会分配内存。简单的方法是在构造函数中

      struct Available_Workshops
      {
          Available_Workshops(int num) : n(num), arr(new Workshop[num]) {}
          int n;
          Workshop *arr;
      };
      

      你可以像这样使用它

      Available_Workshops* initialize(int s[], int d[], int n)
      {
          Available_Workshops *u = new Available_Workshops(n);
          for (int i = 0 ; i < n ; i++)
          {
              Workshop w;
              w.start = s[i];
              w.dur = d[i];
              w.end = w.start + w.end;
              cout << w.end;
              u->arr[i] = w;
          }
          return u;
      };
      

      【讨论】:

      • 我认为初始化成员会更好,并且没有过多考虑,因为输入为 Workshop 对象分配了足够的内存,但我明白你的意思。感谢您指出:)
      • @Vcelist 抱歉,您的原始代码中没有任何内容为 Workshop 对象分配内存。这就是我要指出的错误。我不确定你所说的“输入”是什么意思,但内存分配不会发生,因为你想要它。必须使用new 来分配内存,并且在您的原始代码中除了分配零长度数组(这显然是不够的)之外没有这样的东西。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多