Home > database >  Dynamic array in structs
Dynamic array in structs

Time:09-19

I have a problem using dynamic memory in C. I am creating a struct whose data is a number and a pointer to another struct (in short, an array of struct). The goal is for the parent struct to store an array of another struct using dynamic memory.

The problem I have is to access the cells of the created array, because I don't know if it's due to syntax issues (I'm new to C), or that I'm creating the array wrong, I can't modify the information contained in each cell of the contained array inside the parent struct. I can only modify by default the first cell.

This is my code, any idea or suggestion will be appreciated.

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

typedef struct {
    char string[64];
    void* date;
    void* colour;
} DataState;

typedef struct {
    int number;
    DataState* array;
} Book;

Book* makeBook (int number){
    int a=5;
    void* auxiliary=&a;
    Book* book_A=(Book*)(malloc(sizeof(Book)));
    book_A->number=number;
    book_A->array=(DataState*)(malloc(number*sizeof(DataState))); //creating array of structs inside main struct.
    //And what I want to do is something like this, modify the information contained in cells of the array of structs of the main struct.
    book_A->array[3]->date=auxiliary;
    return book_A;
}

From already thank you very much.

CodePudding user response:

Here:

book_A->array[3]->date=auxiliary;

you assign a value of auxiliary to the 3rd element of an array, but auxiliary is defined as

void* auxiliary=&a;

while a is an automatic variable in your function.

Automatic variables disappear at the return from the function, hence the pointer assigned to book_A->array[3]->date becomes invalid as soon as the return is executed.

CodePudding user response:

If you want the data saved in a to remain valid after makeBook returns, then you must allocate it in more persistent storage than automatic. You've essentially done this:

int* foo()
{
  int a = 5;
  // WRONG, cannot return the address of a local variable
  return &a;
}

int main(void)
{
  int* a_addr = foo();
  // WRONG, invokes undefined behavior
  printf("a = %d\n", *a_addr);
}

If you want a to persist outside of foo, a possible option is:

int* foo()
{
  int* a = malloc(sizeof *a);
  // always check the return value of malloc
  if (a != NULL)
  {
    *a = 5;
  }
  // this is ok. `a` is still in automatic storage, but this _returns_ its
  // value, which is a pointer to data _not_ in automatic storage.
  return a;
}

int main(void)
{
  int* a_addr = foo();
  // still must check here, malloc in `foo` could have failed. Probably
  // better to design an architecture where you only check validity once
  if (a_addr != NULL)
  {
    printf("a = %d\n", *a_addr);  // prints a = 5
    // don't forget to `free(a_addr)` when you're done with it, or you can
    // let the OS clean up the memory when the process exits.
  }
  else
  {
    // handle error how you want
    fprintf(stderr, "Out of mem!\n");
  }
  return 0;
}
  • Related