0

I got a question regarding to static member of structure Here is the scenario:

  • Need 2d array variable to retain its values even after exited from the function in another C files. Subsequent call from main()-in another C file, to the function will use that last value and continue to do calculation to produce and update new values(retained also). So, I I think I need to use static for that array.

  • The 2D array is member of an 2D structure. I need 2D structure for identity purposes for the 2d array. Lets say I got identity[row][column] with member[5][5], I need statically define the member throughout the call from main(). But static for structure member is not allowed in C as I notice.

code i am trying on:

//in function.h

 #define row 2
 #define column 5
 int function(int rowNUM);

  //in function.c
int function(int rowNUM)
{
typedef struct {
    static int member[5][5];
    int y[5][5];
    int forg;
} mystruct;

mystruct identity[row][column];// declare the identity as structure array

int columnNUM;
int c;
int d;

//----try to initialize member to 1
for (columnNUM=0;columnNUM<column;columnNUM++)
{
for (c=0;c<5;c++)
   {
for(d=0;d<5;d++){
   identity[rowNUM][columnNUM].member[c][d]=1;
       }
    }
}


//----try to update member--- The values should retain for subsequent call from main
for (columnNUM=0;columnNUM<column;columnNUM++)
{
for (c=0;c<5;c++)
   {
for(d=0;d<5;d++){
   identity[rowNUM][columnNUM].member[c][d]=1+identity[rowNUM][columnNUM].member[c][d]; // to update member new value
       }
    }
}
}


// in main.c

main()
{
function(1);
function(2);// member here is in different identity from function (1)
function(1);//member should retain its value from function(1)
function(2);//member should retain its value from function(2)
}

Any other suggestion is welcomed if this is not the way to achieve the goal. I am quite new in programing Please help me on this.

danteDev
  • 35
  • 7

3 Answers3

0

If you only want a member of the struct to be static, your best option will be to make a static type in the function, which in your case would be a static 2D array, and do the assignment to the [stack] structure when the function is called.

Eg:

.. function(...)
{
  static int b[2][2]
  typedef struct { int a[2][2] } struct1;
  struct1 x[2][2];
  x->a = b;
}
engineer14
  • 607
  • 4
  • 13
  • I got the " error : request for member ‘a’ in something not a structure or union x->a=b; " during compilation. is the "x[][]" here represent "identity[][]" i mention in the OP? – danteDev Jul 27 '16 at 05:52
  • whoops, sorry, i forgot to add the array indices. that should have read x[i][j] = b, where i and j are some iter vars – engineer14 Jul 27 '16 at 19:44
0

You have defined a 2d array of structs, which is really hard to statically initialize because each struct contains matrices of ints. Also, you can't have only a member of a struct static, the whole structure has to be defined static.

The easiest way I can think of doing what you want is defining an static matrix of mystructs and a helper variable to initialize it just on the first call, ie,

//in function.c
#include <stdbool.h>

int function(int rowNUM)
{
    typedef struct {
        int member[5][5];
        int y[5][5];
        int forg;
    } mystruct;

    // helper flag    
    static bool first_call = true;

    // this is a matrix of (row x cols) mystructs
    static mystruct identity[row][col];

    if (first_call) {
        /* initialize the matrix however you want
           BUT remember to set first_call to false!
        */
        first_call = false;
    }

    // rest of function ...
}

If you don't want to keep the values of the y and forg members (what does forg stand for? is it a typo?), you should split the struct in two, but I can't see why would you want to keep some values of the struct and discard others unless they are temporal variables.

If y and forg are temporal varaibles, you should definitely split your struct definition in two.

Another way of doing that is passing the pointer to the matrix as a parameter to your function, so you can maintain state without using a static variable

int function(int rowNUM, mystruct **identity)

But note that, although most of the times arrays decay to pointers (you can find more information in similar questions to this one), they are not the same thing.

Community
  • 1
  • 1
miravalls
  • 365
  • 1
  • 7
  • Actually I want to group a series of objects (2D arrays of structures) that hold their own properties(members of structure), some of them are matrixes(thats is the reason of 2D array member) that need to keep their values for subsequent calls, some are constants and some are temporal variables. No problem if it is better to separate out the static member from other. I am just trying to organize the data group as an object with identity so that i can access or manage them easily later. I had tried your method and it works with some weird behaviors. I'll post it in the answer here. – danteDev Jul 27 '16 at 13:04
0
void function(int rowNUM){

int c;
int d;
int columnNUM;



typedef struct {
int member[3][3];
}mystruct;

mystruct identity[ROW][COLUMN];
static bool first_call = true;
if (first_call) {
// INTIALIZE each element of member array to 1 
for (columnNUM=0;columnNUM<COLUMN;columnNUM++)//total cell
{
for (c=0;c<3;c++)
   {
for(d=0;d<3;d++){
   identity[rowNUM][columnNUM].member[c][d]=1;
//printf("identity[%d][%d].member[%d][%d]=%d\n",rowNUM,columnNUM,c,d,identity[rowNUM][columnNUM].member[c][d]);
       }
    }
}
first_call = false;
    }



identity[0][0].member[0][0]=identity[0][0].member[0][0]+3;
printf("%d\n", identity[0][0].member[0][0]);
identity[0][0].member[0][1]=identity[0][0].member[0][1]+1;
printf("%d\n", identity[0][0].member[0][1]);



}

The above code produce: first call= 4 2 second call= 7 3 third call= 10 4 Work perfectly fine,nice. But it works fine either I declare

mystruct identity[ROW][COLUMN];

or

static mystruct identity[ROW][COLUMN];

Does it mean I dont need to declare static at all?

danteDev
  • 35
  • 7
  • Yes, you have to declare it `static`: it tells the compiler to put the variables in global memory instead of the stack (those global variables are only accesible from that function). printf is probably not using enough stack variables for you to have different values in the memory region they sit when the function is called. This also depends on the order you declare your stack variables. Notice that you have declared first `c`, `d` and `columnNUM`. If you print `c`, `d` or `columnNUM` before initializing them, you'll probably see random values each time. – miravalls Jul 27 '16 at 21:10
  • without static : printf before intitizlize , c , d show huge random number for the first call to the function and back to normal number for second and third call. With static , every call shows huge random number. The structure array values remain good for both case. Will this cause trouble on the array's values, let say if the program grow longer and more variables declared before or after the static declaration? I am not really understand the memory allocation when declaring the variables. Hope to know more in detail about this..@miravalls – danteDev Jul 28 '16 at 00:40
  • Ok, so in a C program there are several memory regions: the global read only (constants), the global shared variables, the stack and the heap. When you declare a `static` variable, it is placed in the global memory, but it's only defined in the scope you placed it (a variable can only be used within it's scope). The stack is a shared array of bytes that the compiler uses to store the return address of functions, the function parameters and the local variables of a function. When you start a function, the stack variables are allocated in the stack but are not initialized – miravalls Jul 28 '16 at 06:10
  • ...so their initial values are somewhat random: it could be the previous value, or it could be parameters of a previous function call, or it could be random because those bytes have never been initialized, or maybe some of the bytes have been used for shorter stack variables... there are a lot of combinations. There are a lot of sources which you can check for more indepth explanations. I'd recommend you checking http://c.learncodethehardway.org (exercises 17 and 22) or chapter 4 of "The C programming language" from Kernighan and Ritchie. – miravalls Jul 28 '16 at 06:25
  • Thanks @miravalls. Your explanation and suggestion are very helpful. – danteDev Jul 28 '16 at 12:30