By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,538 Members | 869 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,538 IT Pros & Developers. It's quick & easy.

Multidimensional Dynamic Structured Array Acces among Functions

P: 7
Dear everyone,

I am new to this forum and I am realitevely new to C programming so please forgive me for any basic mistakes I'll be making.

I am trying to dynamically allocate the space for the global structured array of pointers that is available to all functions in my program. Since C doesn't allow open array arguments in funciton calls and I do not know the size of the array at compile time I am not sure how to pass this array to the sub- functions. Also, since I am not sure whether the memory allocation will be continuous, just passing the origination address of the array is useless to me.
For example I generate the following arrray:

=========================================


typedef struct{
float Rad; /*to calculate radius */
float Az; /*to calculate azimuth */
float El; /*to calculate elevation */
int Incr; /* Counter for voxel averaging */
float Dm; /* Gridded datamask */
}GRID_STRUCT;


/* Allocationg memory fro 3D Cartesian structured array */
GRID_STRUCT(*grid)[(x_size)][(y_size)][z_size]=malloc(sizeof(*grid));

if( grid == NULL)
{
printf("\nError, memory not allocated for >> grid <<.\n");
exit(1);
}

================================================== ==

Working with this array within its enclosing function is OK.
I can access it and write it easiliy by simply typing:


&( (*grid)(x_position)(y_position) (z_position).Rad) = whatever_address or
whatever =(proper cast) (*grid)(x_position)(y_position) (z_position).Rad;

Now, my question is
how can I pass this structured array to other functions so they can access it in simmilar manner.

It would be nice if I could only use:

extern struct GRID_STRUCT (*grid) [x_size][y_size][z_size];
int temp_Rad=(*grid)[x_smthng][y_smthng][z_smthng].flag;

to access the structure but it doesn't work since compiler gives my an errror

Any advice will be much appreciated.

Thanks

Edo
Apr 11 '07 #1
Share this Question
Share on Google+
12 Replies


P: 7
Help Anyone ?
Apr 13 '07 #2

Savage
Expert 100+
P: 1,764
Help Anyone ?

You need to access it globaly.


Note:To access it globally use ::



Savage
Apr 13 '07 #3

P: 7
Unfortunately I am using C (not C++),so :: will not work
Apr 13 '07 #4

Savage
Expert 100+
P: 1,764
Unfortunately I am using C (not C++),so :: will not work

Then how about using another structure which will contain structured array.


Savage
Apr 13 '07 #5

P: 7
Then how about using another structure which will contain structured array.


Savage
I could do that and sacrifice a little bit of my code "easiness" of programming when I start using same array reference for different structure members (I got to make a huge jumps in memory when I do calculation on structure members). But even then, I am facing the same issue - I do not know the size of the array in advance; therefore I am not sure how to declare it global from within the main(). Header doesn't allow declaration of arrays which will be dynamically allocated later within the program. I still could pass a function call including the starting pointer of the array as well as its size, but in case of multidimensional array dereferencing a pointer get a bit tricky (instead of (*grid)[x][y][z] I got to call (grid)[x*x_size*y_size+y*y_size+z].

I think that the perfect solution to my problem would be some sort of header function that dynamicaly generates the structured array and declares it global. Is such thing possible?
Apr 14 '07 #6

Savage
Expert 100+
P: 1,764
I could do that and sacrifice a little bit of my code "easiness" of programming when I start using same array reference for different structure members (I got to make a huge jumps in memory when I do calculation on structure members). But even then, I am facing the same issue - I do not know the size of the array in advance; therefore I am not sure how to declare it global from within the main(). Header doesn't allow declaration of arrays which will be dynamically allocated later within the program. I still could pass a function call including the starting pointer of the array as well as its size, but in case of multidimensional array dereferencing a pointer get a bit tricky (instead of (*grid)[x][y][z] I got to call (grid)[x*x_size*y_size+y*y_size+z].

I think that the perfect solution to my problem would be some sort of header function that dynamicaly generates the structured array and declares it global. Is such thing possible?
It might be possible to do it with #define.As we know define has two purposes.
First is more simple and it's often used like a simbolic constant but secound is
used for global definitions.

Here is example of secound:

Expand|Select|Wrap|Line Numbers
  1. #define SUBSTITUTE(A,B) { int temp=A;A=B;B=temp;}

So if we could do like:

Expand|Select|Wrap|Line Numbers
  1. #define(SIZE_X,SIZE_Y,SIZE_Z) { GRID_STRUCT(grid)[SIZE_X*SIZE_X_size*SIZE_Y_size+SIZE_Y*SIZE_Y_size+SIZE_Z]=malloc(sizeof(*grid));}

you should be able to access it globaly.


Savage
Apr 14 '07 #7

Expert 10K+
P: 11,448
So if we could do like:

Expand|Select|Wrap|Line Numbers
  1. #define(SIZE_X,SIZE_Y,SIZE_Z) { GRID_STRUCT(grid)[SIZE_X*SIZE_X_size*SIZE_Y_size+SIZE_Y*SIZE_Y_size+SIZE_Z]=malloc(sizeof(*grid));}

you should be able to access it globaly.


Savage
That is not a valid macro definition.If the dimension values are only known at
runtime I'd suggest the following more or less generic routine (in C):
Expand|Select|Wrap|Line Numbers
  1. void* malloc2D(size_t rows, size_t cols, size_t elem) {
  2.    void** mat= malloc(rows*sizeof(void*));
  3.    int i;
  4.    for (i= 0; i < rows; i++)
  5.       mat[i]= calloc(cols, elem);
  6.    return mat;
  7. }
This allocates a two dimensional matrix with 'row' rows, 'col' columns and each
element of the matrix takes up 'elem' bytes.

The followin function frees the thing again:
Expand|Select|Wrap|Line Numbers
  1. void free2D(void* mat, size_t row) {
  2.    void** m= (void**)mat;
  3.    int i;
  4.    if (m)
  5.       for (i= 0; i < row; i++)
  6.          free(m[i]);
  7.    free(m);
  8. }
The same logic can be applied to three and more dimensions.

kind regards,

Jos
Apr 14 '07 #8

P: 7
That is not a valid macro definition.If the dimension values are only known at
runtime I'd suggest the following more or less generic routine (in C):
Expand|Select|Wrap|Line Numbers
  1. void* malloc2D(size_t rows, size_t cols, size_t elem) {
  2.    void** mat= malloc(rows*sizeof(void*));
  3.    int i;
  4.    for (i= 0; i < rows; i++)
  5.       mat[i]= calloc(cols, elem);
  6.    return mat;
  7. }
This allocates a two dimensional matrix with 'row' rows, 'col' columns and each
element of the matrix takes up 'elem' bytes.

The followin function frees the thing again:
Expand|Select|Wrap|Line Numbers
  1. void free2D(void* mat, size_t row) {
  2.    void** m= (void**)mat;
  3.    int i;
  4.    if (m)
  5.       for (i= 0; i < row; i++)
  6.          free(m[i]);
  7.    free(m);
  8. }
The same logic can be applied to three and more dimensions.

kind regards,

Jos

Thanks y'all.
Jos, how can I declare "mat" or "m" as a global variable since size_t_rows and size_t_elements are not know at compile time?
Apr 15 '07 #9

Expert 10K+
P: 11,448
Thanks y'all.
Jos, how can I declare "mat" or "m" as a global variable since size_t_rows and size_t_elements are not know at compile time?
Personally, I'd build a little global struct variable :
Expand|Select|Wrap|Line Numbers
  1. ...
  2. mat_t mat; // global variable
  3.  
and in a .h file I'd put in something like this:
Expand|Select|Wrap|Line Numbers
  1. typedef struct {
  2.    T** mat;
  3.    size_t rows;
  4.    size_t cols;
  5. } mat_t;
  6. ...
  7. extern mat_t mat;
  8. ...
  9. #define ROWS mat.rows
  10. #define COLS mat.cols
  11. #define ELM(x, y) mat.mat[x][y]
then at startup (early in main) I'd initialize the 'mat' struct using the functions
I showed in my previous reply.

kind regards,

Jos
Apr 15 '07 #10

P: 7
Personally, I'd build a little global struct variable :
Expand|Select|Wrap|Line Numbers
  1. ...
  2. mat_t mat; // global variable
  3.  
and in a .h file I'd put in something like this:
Expand|Select|Wrap|Line Numbers
  1. typedef struct {
  2.    T** mat;
  3.    size_t rows;
  4.    size_t cols;
  5. } mat_t;
  6. ...
  7. extern mat_t mat;
  8. ...
  9. #define ROWS mat.rows
  10. #define COLS mat.cols
  11. #define ELM(x, y) mat.mat[x][y]
then at startup (early in main) I'd initialize the 'mat' struct using the functions
I showed in my previous reply.

kind regards,

Jos
I beleive I understand what you're saying. Thanks a lot.
Apr 15 '07 #11

P: 7
Personally, I'd build a little global struct variable :
Expand|Select|Wrap|Line Numbers
  1. ...
  2. mat_t mat; // global variable
  3.  
and in a .h file I'd put in something like this:
Expand|Select|Wrap|Line Numbers
  1. typedef struct {
  2.    T** mat;
  3.    size_t rows;
  4.    size_t cols;
  5. } mat_t;
  6. ...
  7. extern mat_t mat;
  8. ...
  9. #define ROWS mat.rows
  10. #define COLS mat.cols
  11. #define ELM(x, y) mat.mat[x][y]
then at startup (early in main) I'd initialize the 'mat' struct using the functions
I showed in my previous reply.

kind regards,

Jos

I'm sorry. What does T stand for in structure definition? Would be OK to use " float **mat" ?
Apr 15 '07 #12

Expert 10K+
P: 11,448
I'm sorry. What does T stand for in structure definition? Would be OK to use " float **mat" ?
Sure; I didn't know what type you wanted to use for each element so I just typed
the letter T. ;-)

kind regards,

Jos
Apr 15 '07 #13

Post your reply

Sign in to post your reply or Sign up for a free account.