0

I'm trying to send a file to a function that creates a matrix of a struct called Entry, populates it based on the file, and returns the matrix. Right now it's a cascade of errors that I can add if needed, but I suspect I'm just making multiple dumb errors. If there's an easier way that doesn't involve malloc, that would work just as well.

What am I doing wrong and how can I do this properly?

Here's the relevant code:

Entry **matCreate(FILE *fp){

// initialize matrix
Entry matrix = malloc(states * N_CC * sizeof(Entry));

// populate the matrix with initial values
for (int i = 0; i < states; i++) {
  for (int j = 0; j < N_CC; j++) {
    matrix[i][j].next = 99;
    matrix[i][j].action = "D";
  }
}
return matrix;
}

and in the main function:

Entry **matrix = matCreat(fp);

I'm starting the function off with

Entry **matCreate(FILE *fp){

Initializing it with

Entry (*matrix)[N_CC] = malloc( states * sizeof *matrix );

Populating it with:

for (int i = 0; i < states; i++) {
  for (int j = 0; j < N_CC; j++) {
    matrix[i][j].next = 99;
    matrix[i][j].action = "D";
  }
}

And getting it from main with: Entry ourMat = (*matCreate(fp))[N_CC];

But still getting the error: tokenize.c:84:1: warning: return from incompatible pointer type [enabled by default]

Where am I going wrong?

HB-
  • 635
  • 2
  • 8
  • 21
  • is N_CC known at compile time? – M.M Oct 14 '14 at 23:13
  • Yes, it's a constant defined in the header file. – HB- Oct 14 '14 at 23:13
  • 1
    `Entry **` is not compatible with a 2D array; which do you want? – Carl Norum Oct 14 '14 at 23:16
  • see also http://stackoverflow.com/questions/13295318/allocate-a-2d-array-in-c-with-one-dimension-fixed – M.M Oct 14 '14 at 23:18
  • @CarlNorum the term "2D array" can be used to describe an array of pointers to the first element of arrays – M.M Oct 14 '14 at 23:18
  • @MattMcNabb, that's not a 2D array; in C a 2D array is an array of arrays. – Carl Norum Oct 14 '14 at 23:22
  • A 2D array, please. I think that's the source of the last error I'm trying to figure out. What should the declaration for matCreate look like? – HB- Oct 14 '14 at 23:23
  • @CarlNorum it has 2 dimensions and each dimension is an array, so it is a 2D array. You seem to be arbitrarily defining terminology. – M.M Oct 14 '14 at 23:27
  • @Rohawk `Entry **matCreate(FILE *fp)` is the syntax for returning a jagged array. However `Entry (*matrix)[N_CC]` etc. is for allocating an array of arrays. You have to pick which of those two things you want, you can't mix and match. (C doesn't have a "native" multidimensional array). My post covers the array of arrays topic, RADAR's covers the jagged array. – M.M Oct 14 '14 at 23:41
  • 1
    see also [Declaring a C function to return an array](http://stackoverflow.com/questions/1453410/declaring-a-c-function-to-return-an-array), [malloc in C, but use multi-dimensional array syntax](http://stackoverflow.com/questions/3144132/malloc-in-c-but-use-multi-dimensional-array-syntax/) – M.M Oct 14 '14 at 23:43

2 Answers2

2

C doesn't have a true multidimensional array type. You have to either return a jagged array, or return an array of arrays. (Also, since arrays cannot be returned by value; in both cases you have to dynamically allocate the array, and return a pointer to it). Further reading.

For the array of arrays option, you declare and allocate it like this:

Entry (*matrix)[N_CC] = malloc( states * sizeof *matrix );

By using this pattern for the argument to malloc, you avoid having to worry about any complicated stuff.

The type of a function to return this pointer is:

Entry (*matCreate(FILE *fp))[N_CC];

In the calling code you can use the function like this:

Entry (*matrix)[N_CC] = matCreate(fp);
bar( matrix[1][2].action );

You could use a typedef to make all of this simpler syntax. Personally I prefer not to, as then it is less obvious when array-pointer decay is happening.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • Thank you, I confused myself. If I may ask one more question, am I still able to access elements at, for example, "ourMat[0][0].action"? I'm getting the error "subscripted value is neither array nor pointer nor vector". – HB- Oct 14 '14 at 23:43
2

You need to assign malloc return pointer to Entry **

  Entry **matrix;
  matrix= (Entry**)malloc(states * sizeof(Entry *));
  for (i = 0; i < states; i++)
       Entry[i] = malloc(N_CC *   sizeof(Entry));
radar
  • 13,270
  • 2
  • 25
  • 33