1

I am having trouble with initializing a variable matrix in a structure in C. Have been reading a couple of posts(post) but I cant seem to fix it. Don't ask me why but for an assignment I need to initialize a matrix located in a structure.

My code for the struct is:

typedef struct maze{
    int row;
    int column;
    char matrix[row][column];
}maze;

By calling a different function, after reading a certain file, I need to initialize a matrix by its given parameters, so 2 parameters "row" and "column".

My code for the init function is:

struct maze* init_maze(int row, int column) {

    struct maze mazeFilled;
    struct maze *mazePointer;

    mazeFilled.row = row;
    mazeFilled.column = column;

    return mazePointer;
}

But as you can guess this is not working, people already mentioned that it is hard to create a matrix from 2 variables. Could anyone explain what I am doing wrong.

EDIT 1:

I changed my code according to the posts the struct however remains the same. I needed to allocate the pointer so it even stays active outside the scoop.

My new code for the init funct is:

struct maze* init_maze(void) {

    int row = 6;
    int column = 10;
    struct maze *mazePointer = malloc(sizeof (*mazePointer));

    mazePointer->row = row;
    mazePointer->column = column;

    return mazePointer;
}   

EDIT 2:

Think I discoverd what my error was, I did not allocate memory for the matrix. My new init function:

struct maze* init_maze(void) {

int row = 6;
int column = 10;

maze *mazePointer;
mazePointer = malloc(sizeof(maze));
mazePointer->row = row;
mazePointer->column = column;
mazePointer->matrix =  malloc(row * sizeof(char*));

for (int i; i < row; i++) {
    for(int j; j < column; j++) {
    mazePointer -> matrix[i][j] = malloc(1 * sizeof(char*));
    }
}

return mazePointer;

}

I am still not sure how to allocate the memory for just the first array, [i]. Could anyone tell me if I am in the right direction?

Community
  • 1
  • 1
Kipt Scriddy
  • 743
  • 2
  • 14
  • 22
  • Your `init_maze()` function initializes a local variable which is then unused and goes away, then it returns an uninitialized pointer to another local variable. What is this supposed to do? –  Feb 23 '13 at 07:24
  • What I am trying to do is to initialize the struct in the init_maze function with the 2 gives parameters, so row & column – Kipt Scriddy Feb 23 '13 at 07:26
  • then you'll need to `malloc()`ate memory for it. –  Feb 23 '13 at 07:26
  • So to extend the scope of the structure being initialized I need to use malloc when I initialize the struct in the "init_maze" function? – Kipt Scriddy Feb 23 '13 at 07:29
  • 1
    Yes, or you pass in the address of another local variable that resides in the scope of the caller, that's valid as well (think of stdlib functions like `strtok()`). –  Feb 23 '13 at 07:30

1 Answers1

4

Could anyone explain what I am doing wrong?

You are returning a pointer to a local/automatic storage duration structure which is not guaranteed to exist beyond the scope { } of the function.


There are a number of ways to do this. The aim is return a structure which remains alive and active even after returning from the function.


The more commonly used way to do this is to allocate the structure dynamically, populate it and return a pointer to it.

struct maze* init_maze(int row, int column) 
{

    struct maze *pmazeFilled = malloc(sizeof(*pmazeFilled));

    pmazeFilled->row = row;
    pmazeFilled ->column = column;

    return pmazeFilled;
}

Remember the caller must free the allocated memory by calling free on the returned pointer.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • I thought the struct was initialized with the "struct maze mazeFilled;" same for the pointer. – Kipt Scriddy Feb 23 '13 at 07:27
  • 2
    I feel an **urge** to upvote this since you used `sizeof(*mpazeFilled)` instead of `sizeof(SomeAmbiguousAndRiskyTypename)`. –  Feb 23 '13 at 07:31
  • 1
    @KiptScriddy: The structure is local to the function and does not live beyond the function so the pointer points to something that doesnt exist once the function returns. – Alok Save Feb 23 '13 at 07:31
  • @AlokSave Thank you sir, that does make a lot of sense. – Kipt Scriddy Feb 23 '13 at 07:33
  • It's better to use `calloc()` for an "automatic" initialisation of structure. – Eddy_Em Feb 23 '13 at 07:41
  • Its almost working but still the compiler keeps screaming that the row and column are undeclared, can I conclude then that mazePointer->row = row; is not working? – Kipt Scriddy Feb 23 '13 at 08:01
  • @KiptScriddy: You need to update the Q with your new code. Cannot say anything unless you show the code. – Alok Save Feb 23 '13 at 08:02
  • The struct is still exactly the same as listed above and the init_maze is the one you provided me with. Update incoming! – Kipt Scriddy Feb 23 '13 at 08:05
  • 1
    @KiptScriddy The example above is a simplified version of yours: you need to declare `char ** matrix` member inside the struct, instead of `char matrix[nrow][ncol]`. Then you need to correctly allocate space for that and initialize pointers. – Massimiliano Feb 23 '13 at 08:08
  • @Massimiliano so I need to replace the declared matrix with a pointer to a pointer? It is a bit going to fast, could you please explain what you mean? – Kipt Scriddy Feb 23 '13 at 08:17
  • @KiptScriddy Think about this: when you say `malloc(sizeof(*pmazeFilled))`, how does the compiler know the size, if you specify it _only_ after the `malloc`? – Massimiliano Feb 23 '13 at 08:23
  • Okay so I need to specify the size of the matrix within the malloc(sizeof(*pmazeFilled)); line – Kipt Scriddy Feb 23 '13 at 08:32
  • @KiptScriddy No, the point is to make the matrix dynamic (i.e. use a `char**`) and allocate it after you initialized `row` and `column`. – Massimiliano Feb 23 '13 at 08:38
  • Could you please provide me with an example because I cant seem to achieve it – Kipt Scriddy Feb 23 '13 at 08:58