Home > Enterprise >  How do u dynamically fill a struct *array instead of manually making them
How do u dynamically fill a struct *array instead of manually making them

Time:12-09

we've been working on some structs, and decided that we wanted to make them dynamic so we could run a function that would basically make AREASIZE amount of struct areas and store them in our area *array, instead of us having to manually make a block of code with for example 10, 100 or 1000 struct areas and subsequently *Narea amount of subareas.

We've been stuck a couple of hours, and thought it might be more productive to ask where our logic is shit, cuz we cannot seem to find it. The code just crashes in the nested for loop of our create areas function.

Our logic:

  1. we have a struct *array called area, which has a struct *array inside called subareas.
  2. we pass the struct *array area to our function create_areas
  3. create_areas uses the arrow operator to parse through our struct *array areas[i] and then our struct *array subareas[j]. And then fills up the values of our subareas.
  4. before exiting we also assign the other value in our struct *array area, which is its average

In our heads would lead to our struct *array area being filled with 5x areas.

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define MARGIN 70
#define MARGIN2 30
#define SIZE 5
#define NAREA 4
#define AREASIZE 5

typedef struct subarea
{
    int co2_cost, time;
    double average, sensorData[SIZE];
} subarea;

typedef struct area
{
    subarea *subarea_array[NAREA];
    double average;
} area;

void create_areas(area *area_array[NAREA]);
void sensor_data_start(area *area, double start_var);

int main(void)
{
    int co2_counter = 0, time_counter = 0;
    int day_counter = 0;
    int area_number;
    srand(time(NULL));

    area *area_array[AREASIZE] = {};
    create_areas(area_array);
    printf("Hello");
    
    
    return 0;
}

void create_areas(area *area_array[NAREA]) 
{
    printf("create areas\n");
    for (int i = 0; i < AREASIZE; i  )
    {
        printf("First for loop\n");
        for (int j = 0; j < NAREA; j  )
        {
            printf("Second for loop\n");
            area_array[i]->subarea_array[j]->co2_cost = 0;
            printf("Second for loop\n");
            area_array[i]->subarea_array[j]->time = 0;
            printf("Second for loop\n");
            area_array[i]->subarea_array[j]->average = 0;
            printf("Second for loop\n");
            sensor_data_start(area_array[i], 0);
        }
        area_array[i]->average = 0;
    }
}

void sensor_data_start(area *area, double start_var)
{
    for (int i = 0; i < NAREA; i  )
    {
        for (int j = 0; j < SIZE; j  )
        {
            area->subarea_array[i]->sensorData[j] = start_var;
        }
    }
}

CodePudding user response:

Use pointer to structs which will act as array :

typedef struct subarea
{
    int co2_cost, time;
    double average, sensorData[SIZE];
   // note that you can also define sensorSata as pointer and allocate dynamically 
} subarea;

typedef struct area
{
    subarea *subarea_array; // will be allocated dynamically
    double average;
} area;

int main(void)
{
…

    /*allocate soace for the area array     */
    area *area_array = calloc(AREASIZE, sizeof(area));
    create_areas(area_array);
    printf("Hello");

    return 0;
}
     
void create_areas(area *area_array) 
{
    printf("create areas\n");
    for (int i = 0; i < AREASIZE; i  )
    {
        /* allocate space for subarea */
        area_array[i].subarea_array = malloc(sizeof(subarea)*NAREA);
        printf("First for loop\n");
        for (int j = 0; j < NAREA; j  )
        {
            printf("Second for loop\n");
            area_array[i].subarea_array[j].co2_cost = 0;
            printf("Second for loop\n");
            area_array[i].subarea_array[j].time = 0;
            printf("Second for loop\n");
            area_array[i].subarea_array[j].average = 0;
            printf("Sensor dafa start\n");
            sensor_data_start(&area_array[i], 0);
        }
        area_array[i].average = 0;
    }
}

void sensor_data_start(area *area, double start_var)
{
    for (int i = 0; i < NAREA; i  )
    {
        // you can allocate sensorSata here if it was a pointer 
        for (int j = 0; j < SIZE; j  )
        {
            area->subarea_array[i].sensorData[j] = start_var;
        }
    }
}

Other things that could be done for more dynamic is to add the number of subarea in area struct if it is not constant . Same for sensorSata if you make it dynamic.

CodePudding user response:

This:

area *area_array[AREASIZE] = {};

Creates an array of pointers to areas (area *). You have yet to create any areas!.
Thus when you try to access area_array[i]->subarea_array you access unallocated memory, causing a crash. Look into pointers in C if you don't understand why.
Look into the malloc and free functions to actually instantiate your areas. You will also need the sizeof operator.

Note: you will have to do the same with subareas.

In the end you're looking for something like this:

void create_areas(area *area_array[NAREA]) 
{
    printf("create areas\n");
    for (int i = 0; i < AREASIZE; i  )
    {
        area_array[i] = malloc(sizeof(area)); //or malloc(sizeof(*area_array[i]))
        if (area_array[i] == NULL) //always check malloc return value!!
            exit(-1);
        printf("First for loop\n");
        for (int j = 0; j < NAREA; j  )
        {
            area_array[i]->subarea_array[j] = malloc(sizeof(subarea));
            if (area_array[i]->subarea_array[j] == NULL) //always check malloc return value!!
                exit(-1);
            printf("Second for loop\n");
            area_array[i]->subarea_array[j]->co2_cost = 0;
            printf("Second for loop\n");
            area_array[i]->subarea_array[j]->time = 0;
            printf("Second for loop\n");
            area_array[i]->subarea_array[j]->average = 0;
            printf("Second for loop\n");
            sensor_data_start(area_array[i], 0);
        }
        area_array[i]->average = 0;
    }
}

Happy Learning!

  • Related