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.
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.
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;
}
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?
Related
So here is my problem.
I have a struct that has some properties:
struct foo {
const uint8_t propertyA;
int propertyB;
const int propertyC;
typeX propertyD;
typeY propertyE;
};
I then create an array of this struct since I have to represent multiple instances of the object foo:
const int foosQuantity = 8;
struct foo foos[foosQuantity] =
{{ .propertyA=0b11001100, .propertyB=0, .propertyC=140, ...},
{ .propertyA=0b11001000, .propertyB=0, .propertyC=150 ...},
//*** foosQuantity-3 MORE TIMES ***//
{ .propertyA=0b11001000, .propertyB=0, .propertyC=150 ...}}
Until now everything seems to work. However, I have not figured how to send an array of one type of property to a function. For example, I Have this function written in an extern library that takes an array of propertiesA:
void myFunc(const uint8_t *propertyAs, sizeArray){
//*** DO STUFF ***//
}
And I would like to send the properties of my struct directly without having to use a for loop that iterates through the struct array and copies the elements.
int main(){
//*** STUFF ***//
myFunc(foos.propertyA, foosQuantity);
//*** MORE STUFF ***//
return 0;
}
Is this possible?
If the entire struct array already exists in your program's memory, you aren't going to get more efficient than just passing a pointer to the start of the array, the array's length (in elements), and iterating on the propertyA members of the array:
void bar(struct foo *p, size_t len)
{
size_t i;
for(i = 0; i < len; i++)
{
dosomething(p[i].propertyA);
}
}
If you are restricted by assigned specifications to only be allowed to pass an array of propertyA (i.e. uint8_t) to your function, you do have to copy them out of the array of struct foo; there's no way around that.
This is not possible.
You can either
Use a parallel array with just propertyA that gets manipulated along side the array of foo.
Or create an array of propertyA then copy it back in the foo array.
Option 1 is the most memory efficient since it requires the least memory but it may require you to rewrite your a lot of your code.
Option 2 requires the least amount of rework of your code but requires more memory and time.
I'm writing code in C that initializes a bunch of structures using parts of other structures. For example:
//Original structure
struct
{
int foo1;
int foo2;
int foo3;
} orig_struct = {1,2,3};
//New structure
struct
{
int bar1;
int bar2;
} new_struct = {orig_struct.foo1, orig_struct.foo2};
I have to do this for a lot of structures, and the initialization method above makes the code look very clean and readable. To be clear, I don't have any control over the original structures. I'm just creating the new structures to capture data from them.
I ran into an issue when one of the structures had a large array:
//Original structure
struct
{
int foo1;
int foo2[50];
int foo3;
} orig_struct = {1,{2,3,etc},52}; //<--replace "etc" with 48 more int values
//New structure
struct
{
int bar1;
int bar2[50];
} new_struct = {orig_struct.foo1, XXX};
Is there anything I can replace XXX with to initialize the array in the new structure with the values in the array of the original structure? Again, I'd like to keep a clean, consistent look to my code, so keeping it within the curly brackets would be ideal. I know I can manually type out each element of the array within their own curly brackets:
...
} new_struct = {orig_struct.foo1, {orig_struct.foo2[0],orig_struct.foo2[1],orig_struct.foo2[2],orig_struct.foo2[3],etc}
But it's pretty obvious why that can quickly become untenable.
Note that your syntax for initializing new_struct does not work if new_struct has static storage duration, since a constant expression is required in that case.
There really isn't any way to directly assign an array to another array. This is only allowed if the array itself is encapsulated by a structure, and you are using structure assignment. Since your original structure and new structure share a common initial prefix, you could try to exploit this through a union:
struct orig_struct_type orig_struct = {1,{2,3},52};
void some_function ()
{
union {
struct orig_struct_type o;
struct new_struct_type n;
} *u = (void *)&orig_struct;
struct new_struct_type new_struct = u->n;
/* ... */
}
If you are simply trying to reduce code duplication, you can place the array initializer list into a macro.
#define VALUES {2,3,etc} //<--replace "etc" with 48 more int
//Original structure
struct
{
int foo1;
int foo2[50];
int foo3;
} orig_struct = {1,VALUES,52};
void some_function ()
{
struct
{
int bar1;
int bar2[50];
} new_struct = {orig_struct.foo1, VALUES};
/* ... */
}
In c, I see no way to do this within an initializer, as assigning an array is not supported, and expressions must be constant expressions; so a loop or memcpy is not possible during initialization (cf. array initialization reference):
As with all other initialization, every expression in the initializer
list must be a constant expression when initializing arrays of static
or thread-local storage duration:
Later on, of course, you could write memcpy(new_struct.bar2, orig_struct.foo2, sizeof(new_struct.bar2)), but this code is then separated from the struct/variable declaration.
Trying to continue with my assignment but would like to sidetrack and figure out how array of structs work. Not sure if I'm not looking hard enough but I can't seem to find an answer.
Let's say I have one source file, main.c
#include "data.h" //this contains the struct data.
newPerson person[20];
int mainMenu(){
addName();
}
void addName(){
strcpy(person[0].firstName, "George");
}
Doing it this way, I'm able to access the array of struct, however isn't this method considered taboo since my array of person is a global variable?
I then tried moving the array initialization into the main function instead
#include "data.h" //this contains the struct data.
int mainMenu(){
newPerson person[20];
addName();
}
void addName(){
strcpy(person[0].firstName, "George");
}
Doing it this way, when I get to the addName() function, I get a 'person undeclared' error. How can I access the person[] array outside of its function without making it a global variable? Thank for the help in advance. Below I have the example data.h included if needed.
data.h
typedef struct person{
char firstName[20];
char familyName[20];
char telephoneNum[20];
}newPerson;
Just pass parameters to the addName() function.
Example
#include "data.h" //this contains the struct data.
int mainMenu(){
newPerson person[20];
addName(person, 0, "George");
}
void addName(newPerson *person, unsigned int index, const char *const name) {
if ((person == NULL) || (index >= 20))
return; /* ^ this number could be specified with a macro */
/* or via a parameter */
strcpy(person[index].firstName, name);
}
Yeah, pass the variable, person in this case.
person is an array of struct newPerson.
to pass arrays as parameters you should define the function like this
//Option 1, the last dimension without number
void addName(newPerson person[]){
//...
}
//Option 2, as a pointer, but it neets a cast on the call (newPerson*)
void addName(newPerson *person){ //I prefer option 1
//...
}
I want to define a new data type consisting of an array with a size inputted by the user. For example if the user inputs 128, then my program should make a new type which is basically an array of 16 bytes. This structure's definition needs to be global since I am going to use that type thereafter in my program. It is necessary to have a dynamic size for this structure because I will have a HUGE database populated by that type of variables in the end.
The code I have right now is:
struct user_defined_integer;
.
.
.
void def_type(int num_bits)
{
extern struct user_defined_integer
{
int val[num_bits/sizeof(int)];
};
return;
}
(which is not working)
The closest thing to my question, I have found, is in here:
I need to make a global array in C with a size inputted by the user
(Which is not helpful)
Is there a way to do this, so that my structure is recognized in the whole file?
When doing:
extern struct user_defined_integer
{
int val[num_bits/sizeof(int)];
};
You should get the warning:
warning: useless storage class specifier in empty declaration
because you have an empty declaration. extern does not apply to user_defined_integer, but rather the variable that comes after it. Secondly, this won't work anyway because a struct that contains a variable length array can't have any linkage.
error: object with variably modified type must have no linkage
Even so, variable length arrays allocate storage at the point of declaration. You should instead opt for dynamic memory.
#include <stdlib.h>
typedef struct
{
int num_bits;
int* val;
} user_defined_integer;
void set_val(user_defined_integer* udi, int num_bits)
{
udi->num_bits = num_bits;
udi->val = malloc(num_bits/sizeof(int));
}
What you need is a VLA member, as asked about here. Basically, you declare a struct with a size field and one element's worth of storage as last member, and over-allocate it.
Imported from that question :
typedef struct Bitmapset {
int nwords;
uint32 words[1];
} Bitmapset;
Bitmapset *allocate(int n) {
Bitmapset *p = malloc(offsetof(Bitmapset, words) + n * sizeof *p->words);
p->nwords = n;
return p;
}
I want to define a new data type consisting of an array with a size inputted by the user. For example if the user inputs 128, then my program should make a new type which is basically an array of 16 bytes.
This is not possible in C, because C types are a compile-time thing and don't exist at all at run-time.
However, with a C99 conforming compiler, you might use flexible array member. You'll need a struct containing some members and ending with an array without any given dimension, e.g.
struct my_flex_st {
unsigned size;
int arr[]; // of size elements
};
Here is a way to allocate it:
struct my_flex_st *make_flex(unsigned siz) {
struct my_flex_st* ptr
= malloc(sizeof(struct my_flex_st) + siz * sizeof(int));
if (!ptr) { perror("malloc my_flex_st"); exit(EXIT_FAILURE); };
ptr->size = siz;
memset (ptr->arr, 0, siz*sizeof(int));
return ptr;
}
Don't forget to free it once you don't use it anymore.
Of course, you'll need to use pointers in your code. If you really want to have a global variable, declare it as e.g.
extern struct my_flex_st* my_glob_ptr;
Try this method-
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
struct user_defined_integer
{
int *val;
}user_int;
void memory_allocate(int num_bit)
{
int result;
result = (num_bit+CHAR_BIT-1)/CHAR_BIT; // since 8 bit =1 byte
user_int.val=malloc(result*sizeof(int));
if(user_int.val == NULL){
printf("Failed to allocate memory\n");
return ;
}
else
printf("Allocated %d bytes for val\n",result);
}
int main()
{
int num_bit;
printf("Enter the number of bits\n");
scanf("%d",&num_bit);
memory_allocate(num_bit);
// do your stuff here
free(user_int.val); // free the memory at the end;
return 0;
}
I have some code with multiple functions very similar to each other to look up an item in a list based on the contents of one field in a structure. The only difference between the functions is the type of the structure that the look up is occurring in. If I could pass in the type, I could remove all the code duplication.
I also noticed that there is some mutex locking happening in these functions as well, so I think I might leave them alone...
If you ensure that the field is placed in the same place in each such structure, you can simply cast a pointer to get at the field. This technique is used in lots of low level system libraries e.g. BSD sockets.
struct person {
int index;
};
struct clown {
int index;
char *hat;
};
/* we're not going to define a firetruck here */
struct firetruck;
struct fireman {
int index;
struct firetruck *truck;
};
int getindexof(struct person *who)
{
return who->index;
}
int main(int argc, char *argv[])
{
struct fireman sam;
/* somehow sam gets initialised */
sam.index = 5;
int index = getindexof((struct person *) &sam);
printf("Sam's index is %d\n", index);
return 0;
}
You lose type safety by doing this, but it's a valuable technique.
[ I have now actually tested the above code and fixed the various minor errors. It's much easier when you have a compiler. ]
Since structures are nothing more than predefined blocks of memory, you can do this. You could pass a void * to the structure, and an integer or something to define the type.
From there, the safest thing to do would be to recast the void * into a pointer of the appropriate type before accessing the data.
You'll need to be very, very careful, as you lose type-safety when you cast to a void * and you can likely end up with a difficult to debug runtime error when doing something like this.
I think you should look at the C standard functions qsort() and bsearch() for inspiration. These are general purpose code to sort arrays and to search for data in a pre-sorted array. They work on any type of data structure - but you pass them a pointer to a helper function that does the comparisons. The helper function knows the details of the structure, and therefore does the comparison correctly.
In fact, since you are wanting to do searches, it may be that all you need is bsearch(), though if you are building the data structures on the fly, you may decide you need a different structure than a sorted list. (You can use sorted lists -- it just tends to slow things down compared with, say, a heap. However, you'd need a general heap_search() function, and a heap_insert() function, to do the job properly, and such functions are not standardized in C. Searching the web shows such functions exist - not by that name; just do not try "c heap search" since it is assumed you meant "cheap search" and you get tons of junk!)
If the ID field you test is part of a common initial sequence of fields shared by all the structs, then using a union guarantees that the access will work:
#include <stdio.h>
typedef struct
{
int id;
int junk1;
} Foo;
typedef struct
{
int id;
long junk2;
} Bar;
typedef union
{
struct
{
int id;
} common;
Foo foo;
Bar bar;
} U;
int matches(const U *candidate, int wanted)
{
return candidate->common.id == wanted;
}
int main(void)
{
Foo f = { 23, 0 };
Bar b = { 42, 0 };
U fu;
U bu;
fu.foo = f;
bu.bar = b;
puts(matches(&fu, 23) ? "true" : "false");
puts(matches(&bu, 42) ? "true" : "false");
return 0;
}
If you're unlucky, and the field appears at different offsets in the various structs, you can add an offset parameter to your function. Then, offsetof and a wrapper macro simulate what the OP asked for - passing the type of struct at the call site:
#include <stddef.h>
#include <stdio.h>
typedef struct
{
int id;
int junk1;
} Foo;
typedef struct
{
int junk2;
int id;
} Bar;
int matches(const void* candidate, size_t idOffset, int wanted)
{
return *(int*)((const unsigned char*)candidate + idOffset) == wanted;
}
#define MATCHES(type, candidate, wanted) matches(candidate, offsetof(type, id), wanted)
int main(void)
{
Foo f = { 23, 0 };
Bar b = { 0, 42 };
puts(MATCHES(Foo, &f, 23) ? "true" : "false");
puts(MATCHES(Bar, &b, 42) ? "true" : "false");
return 0;
}
One way to do this is to have a type field as the first byte of the structure. Your receiving function looks at this byte and then casts the pointer to the correct type based on what it discovers. Another approach is to pass the type information as a separate parameter to each function that needs it.
You can do this with a parameterized macro but most coding policies will frown on that.
#include
#define getfield(s, name) ((s).name)
typedef struct{
int x;
}Bob;
typedef struct{
int y;
}Fred;
int main(int argc, char**argv){
Bob b;
b.x=6;
Fred f;
f.y=7;
printf("%d, %d\n", getfield(b, x), getfield(f, y));
}
Short answer: no. You can, however, create your own method for doing so, i.e. providing a specification for how to create such a struct. However, it's generally not necessary and is not worth the effort; just pass by reference. (callFuncWithInputThenOutput(input, &struct.output);)
I'm a little rusty on c, but try using a void* pointer as the variable type in the function parameter. Then pass the address of the structure to the function, and then use it he way that you would.
void foo(void* obj);
void main()
{
struct bla obj;
...
foo(&obj);
...
}
void foo(void* obj)
{
printf(obj -> x, "%s")
}