C struct with array size determined at compile time - c

How does one build a struct with an array that can be set differently for each struct, ideally by a parameter? The application being a single data type that supports arrays of different, but fixed lengths
My attempt looks somehting like this, which obviously didnt compile:
struct Data_struct(n)
{
int xData[n];
int test;
};

The only method available is to use a flexible array member.
struct Data_struct {
int test;
int xData[];
};
You would then allocate space for this using malloc():
int n = 4;
struct Data_struct *s = malloc(sizeof(struct Data_struct) + n * sizeof(int));
Note that we had to explicitly allocate additional space for the flexible array.

You can dynamically allocate the array
struct Data_struct
{
int * xData;
int test;
};
....
s.xData = calloc(size, sizeof(int))
and remember to free xData when finished

Normally you would define a variable length array at the end of the struct, and then fix up the size at run-time, e.g.
typedef struct
{
int test;
int xData[1];
} Data_struct;
To allocate a struct such as this with a size of n for xData you'd do soemthing like this:
Data_struct * s = malloc(sizeof(Data_struct) + (n - 1) * sizeof(int));

One might call this ugly but here goes. Use a #define
#define foo(n) struct Data_struct##n { int test; int xData[n]; }
foo(20);
struct Data_struct20 abc;
The foo(20) defines a structure with n = 20 characters.
You could use another #define for the allocation of space if you wish.

Related

Can you create an array of Structure inside of another structure in C language?

Aim : To create a structure of element having certain properties. Then utilize that structure type by creating it's array in another structure.
struct Element
{
int i;
int j;
int x;
};
struct Sparse
{
int r;
int c;
int n;
struct Element *ele;
ele = (struct Element *)malloc(n*sizeof(struct Element));
};
What I wish to know is that which part of the code am I not allowed to write while creating a structure.
The common way to do this is:
struct Element
{
int i;
int j;
int x;
};
struct Sparse
{
int r;
int c;
int n;
struct Element ele[0]; // Make a zero length array
};
struct Sparse* MakeNewSparse(size_t num_ele)
{
struct Sparse* sparse = malloc(sizeof(*sparse) + num_ele*sizeof(struct Element));
return sparse;
}
This works because accessing off the end of a zero-length array is totally legal in C, provided you have allocated memory there.
In this example, we allocate enough space for the struct Sparse, and then enough more contiguous space for the array of struct Element.
After that, accessing element sparse->ele[5] is totally legal.
The line
ele = (struct Element *)malloc(n*sizeof(struct Element));
should not be part of the struct definition - that's something you do at runtime, along these lines:
struct Sparse s; // create new struct Sparse instance
s.n = get_some_size();
s.ele = malloc( s.n * sizeof *s.ele ); // no need for cast
struct in c is syntactically similar with types like int, char, etc. The definition of a struct is for compiler to know how to use variable declared with that struct such as struct Sparse var;. So the definition of a struct is not actually the code itself. It will be used at compile time.
However, malloc() is a function, which will be used at runtime, so it is nonsense to put malloc() in your struct definition.

Changing the size of struct after declared

I have a code contains this structure
struct mystruct{
int a;
int array[1];
};
Directly, after running the code
I mean I will not declare any variable of that structure,the user will enter a number, for example 6.
What I want is to know how I can change the size of that structure.
Like I declared on this form
struct mystruct{
int a;
int array[6];
};
Then I use normally, like this:
struct mystruct var;
//I do not want to add any code here, to appropriate new form
for(int i=0;i<6;i++)
var.array[i]=0;
The typical way to do something like this in straight C (as opposed to C++) is to have just a pointer member in the struct, to point to the array, and then another member of the struct to indicate the size. This generally requires users of the struct to malloc() the array as needed, and to also set the size member to match. Something like:
struct mystruct
{
int size;
int *array;
};
and:
struct mystruct var;
var.array = malloc(6 * sizeof(int));
var.size = 6;
for (int i = 0; i < var.size; i++)
var.array[i] = 0;
Another common paradigm is a linked list.
Of course, in C++ you could just use a std::vector<int>.
You cannot change the declaration of the struct but if it is a variable length array within a struct that you want you do have an option. Declare your struct as:
struct mystruct{
int a;
int array[0];
};
And then when you want to create an instance with n elements in the array do the following:
struct mystruct *a = malloc(sizeof(struct mystruct) + n * sizeof(int));
This will create a memory region large enough to hold the struct and an array of length n. You can then use the array just as you would any other array:
a->array[1] = 5;
(this example assumes the array has at least 2 elements)
To accomplish what you have in your code example you would want to do something like this:
struct mystruct *var = malloc(sizeof(struct mystruct) + 6 * sizeof(int));
for(int i=0;i<6;i++) {
var->array[i]=0;
}
You cannot change an already declared struct, but you can make a new one as you want by modifying the program. You can't change data structures used in the program on the fly while it is running.

Dynamically allocated array of structures in C

I just wanted to know if the following works. I have a struct
called foo that is defined as the following:
struct foo {
char name[255];
int amount;
};
During runtime, I need to create an array of the above structures whose size is dependent on a value I receive from a file's input. Let's say this size is k. Will the following code appropriately allocate a dynamically-sized array of structures?
struct foo *fooarray;
fooarray = malloc(k * sizeof(struct foo));
EDIT: If I want to access members of the structures within these arrays, will I use the format fooarray[someindex].member?
That will work (and your accessing is correct). Also, you can guard against size errors by using the idiom:
fooarray = malloc(k * sizeof *fooarray);
Consider using calloc if it would be nice for your items to start out with zero amounts and blank strings, instead of garbage.
However, this is not a VLA. It's a dynamically-allocated array. A VLA would be:
struct foo fooarray[k];
Yes it will.
On failure it will return 0.
And you have to free the memory returned by malloc when you are done with it
You can access the first member:
fooarray[0].name
fooarray[0].amount
The second as:
fooarray[1].name
fooarray[1].amount
etc..
One more different notation can be used in this approach:
struct foo {
char name[255];
int amount;
};
int main (void)
{
struct foo *fooarray;
struct foo *fooptr[5];
unsigned int i = 0;
for (i = 0; i < 5; i++)
fooptr[i] = malloc(1* sizeof(struct foo));
fooptr[2]->name[3] = 'A';
printf ("\nfooptr[2]->name[3]=%c\n",fooptr[2]->name[3]);
}

Is there a better way to store pairs of ints?

I'm sorry if this is very basic but I'm still learning all that things I can do in C and can't figure out how to do this.
I create pairs of ints in a program and then need to store them. The way I have been doing it so far is by creating a struct:
struct list_el {
short *val; //first value
short *val2; //second value
struct list_el * next;
};
typedef struct list_el item;
I can iterate though the list fine in my normal program but I want to send this to Cuda and am not sure how to transfer the whole struct into Cuda(I know I can make a reference to it). I'm wondering if there's another way I can structure this data so maybe its array? The format I need is in is just simple pairs (something like this 10:5, 20:40, etc..). I thought worst case I can use a char string and have the pairs as characters and then parse them once the main array is in Cuda but I'm wondering if there's a better way create this list of list?
Assuming that you can use two separate arrays, and thinking about how to use/read/write them in CUDA, I will arrange the data in two arrays mainly due to coalesced accesses from global memory wihtin a kernel.
int *h_val1, *h_val2; // allocate arrays in the host and initialize them
Let be N the size of the arrays, allocate the arrays in device memory
int *d_val1, *d_val2;
cudaMalloc( (void**) &d_val1, N * sizeof(int) );
cudaMalloc( (void**) &d_val2, N * sizeof(int) );
and copy data from host to device memory
cudaMemcpy(h_val1, d_val1, N * sizeof(int), cudaMemcpyHostoToDevice);
cudaMemcpy(h_val2, d_val2, N * sizeof(int), cudaMemcpyHostoToDevice);
Configure and launch your kernel to run as much threads as element in the array.
// kernel configuration
dim3 dimBlock = dim3 ( BLK_SIZE, 1, 1 );
dim3 dimGrid = dim3 ( (N / BLK_SIZE) + 1 );
yourKernel<<<dimGrid, dimBlock>>>(d_val1, d_val2);
With this in mind, implement your kernel
__global__ void
yourKernel(int* val1, int* val2, N)
{
// map from threadIdx/BlockIdx to index position
int gid = threadIdx.x + blockIdx.x * blockDim.x;
if (gid < N)
{
int r_val1 = val1[ idx ]; // load from global memory to register
int r_val2 = val2[ idx ]; // load from global memory to register
// do what you need to do with pair val1:val2
}
}
Do not forget to check for errors when calling CUDA functions.
Instead of storing something that references two ints, store something that holds a copy of the ints.
struct list_el {
int val; //first value
int val2; //second value
struct list_el * next;
};
typedef struct list_el item;
Sometimes it is preferable to hold a reference, sometime it is preferable to hold a value. Depending on what you are attempting to do, use the right tool for the job.
By the way, your reference holding struct was only holding references to shorts. To really hold references to ints, you need
struct list_el {
int *val; //reference to first value
int *val2; //reference to second value
struct list_el * next;
};
typedef struct list_el item;
Note that if you hold a reference, the rest of your program should not dispose of the reference's memory before you dispose of the struct reference to prevent accessing memory that is no longer associated with the program (which is an error).
There are other techniques, if you don't want to use list like constructs.
int val[2] = { 1, 2 };
will store two ints, but only two ints.
int val[2][9];
will store nine pairs of two ints, and could easily also be represented as
int val[9][2];
And of course, there is the old standby
int val = 3;
int val2 = 4;
How about just using a two-dimensional array?
int pairs[30][2];
pairs[0][0] = 10;
pairs[0][1] = 5;
// etc.
I'd have to test it, but I think I tested it, and you can even do something like
int pairs[][2] = {{10, 5}, {20, 40}, ...};
for initialization.
NOTE: This method works well if you know how many pairs you will have ahead of time and the number doesn't grow/shrink (in large amounts). If you have a widely variable number of pairs, sticking with a list of structs and using Edwin's answer would probably be better in the long run.
Having a two dimensional array is a good solution, but I am going to answer as if you are keeping your struct solution.
There's nothing wrong with your storing the short ints in a struct, but I would not store the values in short *. To me it is not worth dynamically allocating memory as you need a new structure.
You could have an array of structs to store this data. Here is an example of a fixed size array of item.
#include <stdio.h>
struct list_el {
short val; //first value
short val2; //second value
};
typedef struct list_el item;
item listA[20];
int main()
{
listA[0].val = 1;
listA[0].val2 = 2;
printf("\n%i %i\n", listA[0].val, listA[0].val2);
return 0
}
Even if you make the argument that you won't know in advance how many of these
structs you will have, I would only allocate space for the array like this:
#include <stdio.h>
#include <stdlib.h>
struct list_el {
short val; //first value
short val2; //second value
};
typedef struct list_el item;
item * p_list_el, * pCurStruct;
int main()
{
int idx;
/* p_list_el is the pointer to the array. Don't modify.
pCurStruct can be modified to walk the array. */
p_list_el = malloc(sizeof(item) * 20);
for(idx=0, pCurStruct=p_list_el; idx < 20; idx++)
{
pCurStruct[idx].val = idx;
pCurStruct[idx].val2 = idx + 1;
}
for(idx=0, pCurStruct=p_list_el; idx < 20; idx++)
{
printf("\n%i %i\n", pCurStruct[idx].val, pCurStruct[idx].val2);
}
free(p_list_el);
}

With mmap() how can dynamically sized structures be created

Hi I have the following scenario
#define CONSTANT 10
struct structA{
int var1;
int var2[CONSTANT];
};
main(){
structA *varA = NULL;
int i;
/* some C code */
varA = mmap(0,..);
for(i = 0; i < CONSTANT; i++){
varA.var2[i] = /* C code */ ;
}
/* C code */
}
Here the number of elements in var2 array of structA is constant and hence the varA.var2[i] can be directly referenced . But If the number CONSTANT is to be determined dynamically during runtime , how should the structure definition be modified?
The cleanest way would be to use a C99 flexible array member:
struct structA{
int var1;
int var2[];
};
Then you can just mmap(NULL, sizeof(int) * (num + 1), ...). Just be careful with flexible array members, sizeof behaves funny with them (doesn't include their size).
If you can't / won't use a flexible array member, you can use a pointer instead of an array and mmap memory separately for it.
The most common way to do this is:
struct structA{
int var1;
int var2[1];
};
It's not really an array with a single element, because you allocate more memory than the size of a structA.
The number CONSTANT cannot be determined dynamically at runtime, since it affects the structure size.
The usual trick for what you're trying to do (I'm not sure if it's strictly valid C but it's very common) is to create
struct structA{
int var1;
int var2[0];
};
and when you map or allocate, allocate (sizeof(structA) + sizeof(int) * CONSTANT) bytes.

Resources