简体   繁体   中英

struct members gets cleared when accessed

First off, I'd like to apologize if my explanation is bad, English isn't my first language. I'll be happy to try and explain better if you didn't understand what I wrote here.

I'm trying to solve this problem . I have an array of struct (Workshop) which is a member of another struct (Available_Workshops). My issue is that all data members of all instances of the Workshop struct in the array gets cleared after the first iteration of the for loop in the CalculateMaxWorkshops function which consequently leads to a segmentation fault after the first loop. I tried using vectors and dynamic arrays, but the the issue still occurs.

Here's my code.

#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
    }
}

I can only edit the above, the code below is locked in the site editor.

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;
}

I tried a different approach in the CalculateMaxWorkshops function and it caused a different issue.

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;
    }
}

The issue this time is that the array gets "off-setted" backwards. In other words, data stored in arr[i] becomes stored in arr[i-1] and the data at arr[ni-1] becomes reinitialized.

In summary, The first issue is that data is turning NULL, while the second issue is that data is being off-setted backwards and becoming reinitialized, for example start = -17891602 .

In this function, you are returning a pointer that stores the address of a local variable:

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

Dereferencing the pointer returned by this function invokes undefined behavior.

You need to allocate memory for this pointer:

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

and then remember to delete this memory later.

In general, I would suggest using std::unique_ptr , or preferably, avoiding pointers entirely. However, since you cannot change main , that is not an option you have.

In addition to the problem cigien pointed out, you have another problem here

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

arr is a pointer to a zero length array (since n is zero). But here

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

you treat it as if it has a length n .

You need to allocate memory for enough workshops. Simple way to do that would be in a constructor

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

which you can then use like this

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;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM