cdining-philosopher

Dynamic Memory allocation of array inside structure in C


I'm doing dining-philosopher problem in C for assignment. And got stuck very begining of my code.

I decided each philosopher to be structure, and forks to be int array.

But I can't use global variable in this assignment.

So, I have to include shared variable in philosopher structure to pass them for arguments of thread routine.

Here is my problem - how to include int array in structure if I can't know proper size of them when initializing?

My plan is just include pointer variable in structure then allocate array's address using &.

But It doesn't work :

#include <stdlib.h>

/* inside structure*/
typedef struct s_share {
    int **forks;
} t_share;

/* outside structure */
typedef struct s_philo {
    t_share *share;
} t_philo;


int main(void)
{
    t_philo *philo;
    int     *forks;
    int     i;

    i = 0;

    /* malloc structure arrary philo, size = 10 */
    philo = (t_philo *)malloc(sizeof(t_philo) * 10);

    /* malloc int arrary forks, size = 100 */
    forks = (int *)malloc(sizeof(int) * 100);
    while (i < 10)
    {
        philo[i].share->forks = &forks; //error
        i++;
    }

}

Output : segmentation fault

I tested share->forks size like this :

printf("size of forks : %ld\n", sizeof(philo->share->forks));

Output was 8. It's enough size to store int * pointer. Through this I know It's not the memory allocation problem.

Then what is problem? Can someone check this for me?


Edit : When I try to malloc directly philo->share->forks, I got same error.

typedef struct s_share {
    int *forks;
} t_share;

typedef struct s_philo {
    t_share *share;
} t_philo;


int main(void)
{
    t_philo *philo;
    int     *forks;
    int     i;

    i = 0;
    philo = (t_philo *)malloc(sizeof(t_philo) * 10);
    while (i < 10)
    {
       philo[i].share->forks = (int *)malloc(sizeof(int) * 100); //error
        i++;
    }
}

I thought it's because when philo initialized, sizeof operator calculated forks's memroy to be 8 - which required for pointer.

Is there something wrong?


Edit 2 : To clear my question,

It's easy to solve this problem, if I write size of array in structure definition.

typedef struct s_share {
    int forks[100];
} t_share;

typedef struct s_philo {
    t_share *share;
} t_philo;

but according to my assignmet I have to get philosopher's number from cmd. So I can't do that. Above is simple version of my origin code


Sorry, Edit 2 is wrong :


typedef struct s_share {
    int forks[100];
} t_share;

typedef struct s_philo {
    t_share *share;
} t_philo;


int main(void)
{
    t_philo *philo;
    t_share *share;
    int     *forks;
    int     i;

    i = 0;
    philo = (t_philo *)malloc(sizeof(t_philo) * 10);
    while (i < 10)
    {
        philo[i].share->forks[i] = 1;
        i++;
    }
}

Output

zsh: segmentation fault  ./a.out

I still got segfault when I write array size in struct definition.

I used calloc to initialize all member in my struct but same error occurs :

typedef struct s_share {
    int **forks;
} t_share;

typedef struct s_philo {
    t_share *share;
} t_philo;


int main(void)
{
    t_philo *philo;
    t_share *share;
    int     *forks;
    int     i;

    i = 0;
    philo = (t_philo *)calloc(10, sizeof(t_philo));
    forks = (int *)calloc(100, sizeof(int));
    while (i < 10)
    {
        philo[i].share->forks = &forks; //error
        i++;
    }
}

Edit 4: I finally found error. It's because I didn't malloc 'share' struct in philo struct

typedef struct s_share {
    int **forks;
} t_share;

typedef struct s_philo {
    t_share *share;
} t_philo;


int main(void)
{
    t_philo *philo;
    int     *forks;
    int     i;

    i = 0;
    philo = (t_philo *)malloc(sizeof(t_philo) * 10);
    forks = (int *)malloc(sizeof(int) * 100);
    while (i < 10)
    {
        philo[i].share = (t_share *)malloc(sizeof(t_share)); //here
        philo[i].share.forks = &forks;
        i++;
    }
}

That one line -allocating struct share- solved problem.

Or, I can modify philo struct definition like this :

typedef struct s_philo {
    t_share share; //not pointer, just struct
} t_philo;

In this way, I can automatically malloc struct share.

I got confused in this point. Thanks for helping!


Solution

  • this line

    philo[i].share->forks
    

    Is dereferencing the pointer 'share' which is not set. You called malloc and did not set any values, so the data inside your allocated buffer is 'garbage' data.