0

In my data.h file I have:

typedef struct {
    double ***grid;
} Solver;

In my .c file I have

static Solver _solver;

which first makes a call to a function to do some allocation on grid such as

_solver.grid = malloc(....);

//then makes a call to

GS_init(_solver.grid);

The GS_init function is declared in GS.h as:

void GS_init(double ***grid);

When I try to compile, I get two errors:

the struct "<unnamed>" has no field "grid"
GS_init(_solver.grid)
^

and

too many arguments in function call
GS_init(_solver.grid)
^

Any ideas what is going wrong here?

4
  • Be scared when you see triple pointers. They are occasionally a good idea; they are very seldom a good idea. Commented Jan 29, 2010 at 17:41
  • Does GS.h include data.h? Superficially, if both headers are in included in the code in your '.c' file, there shouldn't be a problem. Commented Jan 29, 2010 at 17:45
  • gs.h and data.h are separate files. I have already modified the code to use a triple pointer (3d array) and it ran a lot faster. Now I am trying ot move the local copy of the data I had in my method back out to the solver structure. Commented Jan 29, 2010 at 17:58
  • oh, yes, i see what you were saying now. yes, in the .c file, both are included Commented Jan 29, 2010 at 18:30

1 Answer 1

1

This code compiles with 'gcc -Wall -Werror -c':

data.h

typedef struct
{
    double ***grid;
} Solver;

gs.h

extern void GS_init(double ***grid);

gs.c

#include "data.h"
#include "gs.h"
#include <stdlib.h>

static Solver _solver;

void anonymous(void)
{
    _solver.grid = malloc(32 * sizeof(double));
    GS_init(_solver.grid);
}

Derek asked:

Why does this work? Is it because of the extern keyword?

The 'extern' is not material to making it work, though I always use it.

When I have to flesh out GS_init() in, say compute.c, would I write void GS_init(double ***grid){ //loop over grid[i][j][k] setting to zero }

Sort of...yes, the GS_init() code could do that if the data structure is set up properly, which is going to need more information than there is currently visible in the structure.

For the compiler to process:

grid[i][j][k] = 0.0;

the code has to know the valid ranges for each of i, j, and k; assume the number of rows in each dimension are Ni, Nj, Nk. The data 'structure' pointed to by grid must be an array of Ni 'double **' values - which must be allocated. Each of those entries must point to Nj 'double *' values. So, you have to do more allocation than a single malloc(), and you have to do more initialization than just setting everything to zero.

If you want to use a single array of doubles only, you will have to write a different expression to access the data:

grid[(i * Ni + j) * Nj + k] = 0.0;

And under this scenario, grid would be a simple double * and not a triple pointer.

Sign up to request clarification or add additional context in comments.

3 Comments

why does this work? because of the extern keyword? when I have to flesh out GS_init() in, say compute.c, would i write void GS_init(double ***grid){ //loop over grid[i][j][k] setting to zero }
It should be Ni and Nj, not Ni-1 and Nj-1.
@BlueRaja: yes, you're right; thanks. Too long since I had to do this sort of stuff.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.