Dynamic Memory allocation of array inside structure in C - 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!

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.

// add begin
t_share* new_share = (t_share*)malloc(sizeof(t_share));
philo[i].share = new_share;
// add end
// don't use &forks
philo[i].share->forks = forks; //error
i++;
// need forks++
forks++;

Related

Why when I try to access array of structures it returns random values? (C)

I have a function that returns pointer to array of structures. However, when I try to access any of the values of returned structure, it prints random symbols.
#include <stdio.h>
struct MY {
int i;
char string[30];
};
struct MY* myFunc() {
struct MY arrayOfStructs[3];
struct MY tempStruct;
struct MY* arrayOfStructsPtr = arrayOfStructs;
tempStruct.i = 1;
tempStruct.string[0] = 'H';
tempStruct.string[1] = 'i';
arrayOfStructs[0] = tempStruct;
tempStruct.i = 2;
tempStruct.string[0] = 'L';
tempStruct.string[1] = 'o';
arrayOfStructs[1] = tempStruct;
tempStruct.i = 3;
tempStruct.string[0] = 'M';
tempStruct.string[1] = 'Y';
arrayOfStructs[2] = tempStruct;
return arrayOfStructsPtr;
}
int main()
{
struct MY* arrayOfStructs = myFunc();
for(int i = 0; i < 3; i++) printf("%d\n", arrayOfStructs[i].i);
return 0;
}
You return a reference to the local array which stops to exist when function returns. It is Undefined Behaviour.
You need:
struct MY* myFunc(void) {
static struct MY arrayOfStructs[3];
or
struct MY* myFunc(void) {
struct MY *arrayOfStructs = malloc(3 * sizeof(*arrayOfStructs));
or pass the buffer allocated by the caller.
struct MY *myFunc(struct MY *arrayOfStructs) {
/* .... */
If you dynamically allocate memory you should free it after use
You return a pointer to a local variable which is out of scope when the function returns. Some alternatives:
The caller main() allocates variable and pass it to myFunc() for initialization.
#include <stdio.h>
#include <string.h>
#define N 3
struct MY {
int i;
char string[30];
};
void myFunc(struct MY arrayOfStructs[N]) {
char *strings[N] = { "Hi", "Lo", "MY" };
for(size_t i = 0; i < N; i++) {
arrayOfStructs[i].i = i + 1;
strcpy(arrayOfStructs[i].string, strings[i]);
}
}
int main() {
struct MY arrayOfStructs[N];
myFunc(arrayOfStructs);
for(int i = 0; i < N; i++)
printf("%d\n", arrayOfStructs[i].i);
}
As used here you don't really need to store i as it's just index of the struct + 1.
myFunc() dynamically allocate the variables with malloc() and return the pointer. Caller is responsible for free'ing the allocated memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
struct MY {
int i;
char string[30];
};
struct MY *myFunc() {
struct MY *arrayOfStructs = malloc(N * sizeof *arrayOfStructs);
if(!arrayOfStructs) return NULL; // malloc failed
char *strings[N] = { "Hi", "Lo", "MY" };
for(size_t i = 0; i < sizeof strings / sizeof *strings; i++) {
arrayOfStructs[i].i = i + 1;
strcpy(arrayOfStructs[i].string, strings[i]);
}
return arrayOfStructs;
}
int main() {
struct MY *arrayOfStructs = myFunc();
if(!arrayOfStructs) return 1;
for(int i = 0; i < N; i++)
printf("%d\n", arrayOfStructs[i].i);
free(arrayOfStructs);
}
myFunc(): make variables static (not recommended).

Dynamically allocating memory for a variable inside a struct as int,double etc

I Have a struct as
struct myStruct {
int message;
void*packet;
};
is it ok to dynamically allocate memory from a function in runtime like this
struct myStruct* create(int type, int length)
{
if(type==1)
myStruct->packet = (int *)malloc(length * sizeof(int));
if(type==2)
myStruct->packet = (double *)malloc(length * sizeof(double));
}
so that my packet can be configured as double as well as int?
It is not clear from your snippet when you allocate memory for the message container myStruct. Assuming that it is also being dynamically allocated, you can create memory for it and your array simultaneously.
The receiver of this message will need to know how to interpret the information, so we need to encode the information about type and length into it as well. Here is one way to achieve that:
struct myStruct {
int message;
int type;
int length;
};
So this contains the message of your original structure, as well as the information passed into the create() function. Notice that this is just the header, without any of the data allocated yet. We can create specializations with flexible arrays to represent that data.
struct myStructInt {
struct myStruct hdr;
int data[];
};
struct myStructDouble {
struct myStruct hdr;
double data[];
};
Each distinct supported array can have its own specialization. Now, your create() function can do a single allocation for the entire message.
struct myStruct * create (int type, int length) {
struct myStruct hdr = { 0, type, length };
struct myStruct *m;
size_t total = 0;
switch (type) {
case 1: total = sizeof(struct myStructInt) + length * sizeof(int);
break;
case 2: total = sizeof(struct myStructDouble) + length * sizeof(double);
break;
/* ... */
}
if ((m = malloc(total)) != NULL) *m = hdr;
return m;
}
The caller would know what type of message it wanted to create, so it can properly cast the pointer to the intended type after it receives the pointer from create().
In your example there's an error: the struct is not allocated and the create function doesn't return the allocated structure. You cannot do this: myStruct->packet = (int *)malloc(length * sizeof(int)); without before allocating myStruct.
I have written two samples where is used an enum to enumerate the type of packet array in the structure and a union packet to manage the
different kind of data.
The structure myStruct will contain info about the type of contents of the packet union and its array dimension.
The function create, in the 1st sample, uses only one malloc to allocate both structure space and packet space. In this way is more simple to deallocate the structure. Furthermore create may return an error on the parameter err to indicate error conditions, on the other hands in case of error, in this version of 1st sample, the return value of the function shall be NULL.
If you don't need to allocate the structure I've written a second sample that allocates only the space for the union packet (the 2nd sample above). Here the function create allocates packet for an already allocated structure and returns 0 or an error value if an error occurs.
Here the 1st sample:
#include <stdio.h>
#include <stdlib.h>
typedef enum myType {
myTypeDouble,
myTypeInt
} myType;
typedef struct myStruct {
myType myType;
size_t length;
// int message; in this sample this has no mean!
union {
int * i;
double * d;
} packet;
} myStruct;
myStruct * create(myType mtype, size_t length, int *err)
{
myStruct * ms = NULL;
int retVal=0;
size_t mlen = sizeof (myStruct);
switch(mtype) {
case myTypeInt:
mlen += sizeof(int)*length;
break;
case myTypeDouble:
mlen += sizeof(double)*length;
break;
default:
mlen=0;
retVal=1;
break;
}
if (mlen) {
ms = malloc(mlen); // One malloc allocates struct and packet.
if (ms != NULL) {
ms->length = length;
ms->myType=mtype;
/* Don't care myType, the usable space is after
the structure dimension then ms->packet.i=[...]
should be also ms->packet.d=(double *)(ms+1);
*/
ms->packet.i=(int *)(ms+1);
} else {
retVal=2;
}
}
if (err)
*err=retVal;
return ms;
}
int main(void) {
#define PACKLEN 20
myStruct * ms[2]={NULL,NULL};
int err=0;
int i;
ms[0]=create(myTypeInt,PACKLEN,&err);
if (err)
return 1;
ms[1]=create(myTypeDouble,PACKLEN,&err);
if (err) {
if (ms[0])
free(ms[0]);
return 2;
}
for (i=0;i<PACKLEN;i++) {
ms[0]->packet.i[i] = i*2+1;
ms[1]->packet.d[i] = 2.1*(double)(i+1);
}
for (i=0;i<PACKLEN;i++) {
printf("%d ",ms[0]->packet.i[i]);
}
puts("");
for (i=0;i<PACKLEN;i++) {
printf("%g ",ms[1]->packet.d[i]);
}
puts("");
if (ms[0])
free(ms[0]);
if (ms[1])
free(ms[1]);
}
Here the 2nd sample:
#include <stdio.h>
#include <stdlib.h>
typedef enum myType {
myTypeDouble,
myTypeInt
} myType;
typedef struct myStruct {
myType myType;
size_t length;
// int message; don't care in this sample.
union {
int * i;
double * d;
} packet;
} myStruct;
int create(myStruct * ms, myType mtype, size_t length)
{
int retVal=0;
size_t mlen = 0;
if (!ms) {
return 1;
}
switch(mtype) {
case myTypeInt:
mlen = sizeof(int)*length;
break;
case myTypeDouble:
mlen = sizeof(double)*length;
break;
default:
mlen=0;
retVal=2;
break;
}
if (mlen) {
/* Don't care myType! ms->packet.i=[...]
should be also ms->packet.d=malloc(mlen);
*/
ms->packet.i=malloc(mlen);
if (ms) {
ms->length = length;
ms->myType=mtype;
} else {
retVal=3;
}
}
return retVal;
}
int main(void) {
#define PACKLEN 20
myStruct ms[2];
int err=0;
int i;
ms[0].packet.i=NULL;
ms[1].packet.d=NULL; // Although the use of .i has the same behaviour
err=create(&ms[0],myTypeInt,PACKLEN);
if (err)
return 1;
err=create(&ms[1],myTypeDouble,PACKLEN);
if (err) {
if (ms[0].packet.i)
free(ms[0].packet.i);
return 2;
}
for (i=0;i<PACKLEN;i++) {
ms[0].packet.i[i] = i*2+1;
ms[1].packet.d[i] = 2.1*(double)(i+1);
}
for (i=0;i<PACKLEN;i++) {
printf("%d ",ms[0].packet.i[i]);
}
puts("");
for (i=0;i<PACKLEN;i++) {
printf("%g ",ms[1].packet.d[i]);
}
puts("");
if (ms[0].packet.i)
free(ms[0].packet.i);
// Although the use of packet.i has the same behaviour.
if (ms[1].packet.d)
free(ms[1].packet.d);
}
As suggested in the comments, you can solve this problem by using a union.
typedef enum {INT_ARR, DOUBLE_ARR} myType;
struct myStruct {
myType type;
union {
int *iArr;
double *dArr;
} value;
}
The advantage of using a union is that the iArr pointer and dArr pointer occupy the same memory. Which field you should access the pointer as is determined by the type field.
The create function you've supplied is seemingly incomplete, as it never allocates memory for the struct or returns anything. If you choose to use the union scheme, you could write it like this:
struct myStruct *create(myType type, int length) {
// Allocate struct
struct myStruct *res = malloc(sizeof(struct myStruct));
res->type = type;
if(type == INT_ARR)
res->iArr = malloc(length * sizeof(int));
else if(type == DOUBLE_ARR)
res->dArr = malloc(length * sizeof(double));
return res;
}
Note that you should free() the result returned by this create function once you are done with the struct.

how to do dynamic allocation in boundless array

Well I am wanting to change the way my structures are written, currently I use array and I need to limit its use, but I wanted a way to create a dynamic array that is the size of the reading done, without always having to edit the array value.
Current Code:
struct sr_flag {
int value_flag;
};
struct er_time {
int value_time;
};
struct se_option {
struct sr_flag flag[50];
struct er_time time[50];
};
struct read_funcs
struct se_option *option;
void (*option_func) (void);
...
}
struct read_funcs func_;
struct read_funcs *func;
int sr_flags(int i, int fg, int val) {
if(i < 0)
return 0;
return func->option[i].flag[fg].value_flag = val;
}
void option_func(void) {
struct se_option fnc;
fnc.option = malloc(500 * sizeof(*(fnc.option)));
}
void read_fnc() {
func = &func_;
func->option = NULL;
func->option_func = option_func;
}
I look for a way to remove the array amount [50] instead each time the sr_flags function is executed the limit is raised
Example: sr_flags function executed 1x array would be [1] if executed 2x would be [2]
I also think about doing the same with the option_func function
I tried using the following more unsuccessfully
struct se_option {
struct sr_flag *flag;
struct er_time time[50];
};
int sr_flags(int i, int fg, int val) {
if(i < 0)
return 0;
func->option[i].flag = malloc(1 * sizeof(*(func->option[i].flag)));
return func->option[i].flag[fg].value_flag = val;
}
int main () {
for(int i < 0; i < 10; i++)
sr_flags(i, 1, 30);
return 0;
}
I'm not 100% certain on what it is you want but I think you just want to call realloc and increase the size by the amount you provide. And that's very easy to do, as for the values you want with the arrays I'm not sure so I just used a placeholder value.
#include <stdio.h>
#include <stdlib.h>
struct sr_flag {
int value_flag;
};
struct er_time {
int value_time;
};
struct se_option {
struct sr_flag* flag;
struct er_time* time;
};
void allocateflags(struct se_option* options, int size, int val){
options->flag = realloc(options->flag, size*sizeof(struct sr_flag));
struct sr_flag* flag = options->flag+size-1;
flag->value_flag = val;
}
void allocatetime(struct se_option* options,int size, int val){
options->time = realloc(options->time, size*sizeof(struct er_time));
struct er_time* time = options->time+size-1;
time->value_time = val;
}
void displayflagvalues(struct se_option* options,int size){
for(int index = 0; index < size ; ++index){
printf("flag: %i\n",options->flag[index].value_flag);
}
}
void displaytimevalues(struct se_option* options, int size){
for(int index = 0; index < size ; ++index){
printf("time: %i\n",options->time[index].value_time);
}
}
int main(){
struct se_option options = {0};
for(int index = 0; index < 10; ++index){
allocateflags(&options, index,index);
allocatetime(&options, index,index);
}
displayflagvalues(&options, 10);
displaytimevalues(&options,10);
return 0;
}
The code creates an se_option structure wheren sr_flag and er_time pointers are null. Then there's two functions one allocateflags and the other allocatetime, both of which call realloc with the size you provide. When you call realloc, all previous memory is copied over to the new array. Also free is called automatically by realloc.
This step
struct sr_flag* flag = options->flag+size-1;
flag->value_flag = val;
struct er_time* time = options->time+size-1;
time->value_time = val;
Is slightly redundant but it was just to show the newest array can hold the value. If you understand pointer arithmetic, all its doing is incrementing the pointer to the last position then subtracting 1 struct size and setting that value. Basically setting the value of the final array in the pointer.

How to allocate memory with different type in C?

I have the following code in C:
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
int student[1];
} People;
#define NUM_OF_PEOPLE
void *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE);
How could I find the pointer to the memory point to the first element of struct Student in the memory?
I try to do it in the following way:
int i = 0;
for(i = 0; i < NUM_OF_PEOPLE; i++)
{
Student * student_p = p.student[NUM_OF_PEOPLE];
}
It does not work, so can we allocate memory in the way?
And how to find the first element of struct Student in the memory?
What you have is an ancient way of having a flexible array member, which was technically also undefined behavior.
You are looking for this.
First, you need to define your struct like this (I don't know what the ints before the Students are, so let's just call it id):
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
Student student;
} StudentAndId;
typedef struct
{
int id;
StudentAndId students[];
} People;
Note the lack of size in the array inside People. Now you do this:
People *p = malloc(sizeof(People) + sizeof(StudentAndId[NUM_OF_PEOPLE]));
Then you can access students inside p as if it was an array of NUM_OF_PEOPLE elements.
Remember to compile with C99 (or C11) support. With gcc that would be -std=c99 or -std=gnu99.
This will allocate memory for storing the date but how you access it depends on how you store date. using C pointers you can store and access data using this structure and allocation but accessing the members will not be direct. it will involve pointer arithmetic. So better to use other structure if possible. If using this way of allocation then you need to do pointer arithmetic to get the next elements.
Try this:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
int student[1];
} People;
#define NUM_OF_PEOPLE 10
int main()
{
People *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE);
int* id = (int*)(p+1);
Student* s = (Student*)(id+NUM_OF_PEOPLE);
printf("Size of People : %d\n", sizeof(People));
printf("p points to : %p\n", p);
printf("id points to : %p\n", id);
printf("s points to : %p\n", s);
}
Here's a sample output:
Size of People : 8
p points to : 0x80010460
id points to : 0x80010468
s points to : 0x80010490
You may want to add the id field to your Student data structure, e.g.:
typedef struct {
int id;
int age;
int phoneNumber;
} Student;
Then, you can define a structure having a fixed header (in this case, this can be the number of students), followed by a variable-sized array of Students:
#define ARRAY_OF_ANY_SIZE 1
typedef struct {
int count;
Student students[ARRAY_OF_ANY_SIZE];
} People;
This blog post explains this technique of having "arrays of size 1", including a discussion of the alignment problem.
I won't repeat the original blog post code here. Just consider that you can use the portable offsetof() instead of the Windows-specific FIELD_OFFSET() macro.
As a sample code, you may want to consider the following:
#include <stdio.h> /* For printf() */
#include <stddef.h> /* For offsetof() */
#include <stdlib.h> /* For dynamic memory allocation */
typedef struct {
int id;
int age;
int phoneNumber;
} Student;
#define ARRAY_OF_ANY_SIZE 1
typedef struct {
int count;
Student students[ARRAY_OF_ANY_SIZE];
} People;
int main(int argc, char* argv[]) {
People* people;
const int numberOfStudents = 3;
int i;
/* Dynamically allocate memory to store the data structure */
people = malloc(offsetof(People, students[numberOfStudents]));
/* Check memory allocation ... */
/* Fill the data structure */
people->count = numberOfStudents;
for (i = 0; i < numberOfStudents; i++) {
people->students[i].id = i;
people->students[i].age = (i+1)*10;
people->students[i].phoneNumber = 11000 + i;
}
/* Print the data structure content */
for (i = 0; i < people->count; i++) {
printf("id: %d, age=%d, phone=%d\n",
people->students[i].id,
people->students[i].age,
people->students[i].phoneNumber);
}
/* Release the memory allocated by the data structure */
free(people);
return 0;
}
Output:
id: 0, age=10, phone=11000
id: 1, age=20, phone=11001
id: 2, age=30, phone=11002

C (not ++) a struct of struct array in struct dynamic initialization troubles malloc

I have a small trouble initializing (dynamic) parts of my structures that are in an array. This is what i have so far I am using a sub-routine to create the struct
t_grille_animaux creer_grille(int dim_ligne, int dim_col)
{
t_grille_animaux grille;
grille.la_grille = (t_case_animal **) malloc(sizeof(t_case_animal)*dim_ligne*dim_col);
grille.dim_colonne = dim_col;
grille.dim_ligne = dim_ligne;
grille.nb_predateurs = NULL;
grille.nb_proies = NULL;
return grille;
}
This is my structure:
typedef struct
{
t_case_animal ** la_grille; //2D array
int dim_ligne;
int dim_colonne;
int nb_proies;
int nb_predateurs;
} t_grille_animaux;
typedef struct
{
t_contenu etat;
t_animal animal;
} t_case_animal;
typedef enum {VIDE, PROIE, PREDATEUR} t_contenu;
typedef struct
{
int age;
int jrs_gestation;
int energie;
int disponible;
} t_animal;
(Sorry for the language)
What I get right now is that everything that isn't the struct in the array is fine. But everything in the array is undeclared.
This should do the trick:
#define NUM_ROWS (10)
#define NUM_COLS (15)
grille.la_grille = malloc(NUM_ROWS * sizeof(*grille.la_grille));
for(int row = 0; row < NUM_ROWS; row++)
grille.la_grille[row] = malloc(NUM_COLS * sizeof(**grille.la_grille));
The malloc() function does not (necessarily) initialise the allocated bytes to any value in particular. So after calling malloc(), you should explicitly initialise the allocated data.
Having said that, you have a couple of choices about how you can store your two-dimensional array. It depends on how you want to access the data. Since C does not have true multidimensional arrays, you can either:
declare a single dimension array of size dim_ligne*dim_col of t_case_animal values
declare an array of row pointers of size dim_ligne that each point to another single dimensional array of dim_col values
For the first case, change your declaration of la_grille to:
t_case_animal * la_grille;
and access your values as something like la_grille[j*dim_colonne+i].
For the second case, be sure to initialise your subarrays:
grille.la_grille = (t_case_animal **) malloc(sizeof(t_case_animal*)*dim_ligne);
for (int i = 0; i < dim_ligne; i++) {
grille.la_grille[i] = (t_case_animal *) malloc(sizeof(t_case_animal)*dim_col);
}
In the second case, you would access your values as something like la_grille[j][i].
You can use malloc() to allocate memory for each row. The following code should work:
#include<stdlib.h>
typedef struct
{
int age;
int jrs_gestation;
int energie;
int disponible;
}t_animal;
typedef enum {VIDE, PROIE, PREDATEUR} t_contenu;
typedef struct
{
t_contenu etat;
t_animal animal;
} t_case_animal;
typedef struct
{
t_case_animal ** la_grille; //2D array
int dim_ligne;
int dim_colonne;
int nb_proies;
int nb_predateurs;
} t_grille_animaux;
t_grille_animaux creer_grille(int dim_ligne,int dim_col)
{
t_grille_animaux grille;
grille.la_grille = (t_case_animal**) malloc(sizeof(t_case_animal*)*dim_ligne);
for(int i=0; i<dim_ligne; i++) {
grille.la_grille[i] = (t_case_animal*) malloc(sizeof(t_case_animal)*dim_col);
}
grille.dim_colonne = dim_col;
grille.dim_ligne = dim_ligne;
grille.nb_predateurs = 0;
grille.nb_proies = 0;
return grille;
}
int main(int argc, char* argv[])
{
t_grille_animaux test;
test = creer_grille(3, 4);
}

Resources