What datastructure can be used alternate to 4 dimensional array - c

Currently in my testframework, to keep track of testresults , I am maintaining 4D array : TestResult[domain][client][testno][resourceno]
The testcase basically has 3 loops
For each domain(0-2)
For each client(0-8)
For each resource(0-8)
Execute test1
Store TestResult
Execute test2
Store TestResult
Is there a better datastructure which can be used in C, for this purpose other than 4D array?

Well, let's get to the opposite extrem:
typedef struct
{
// whatever you need...
} Resource;
typedef struct
{
Resource a;
Resource b;
// ...
Resource g;
} Client;
typedef struct
{
Client a;
Client b;
// ...
Client g;
} Domain;
OK, I skipped the Test struct and the one containing the all the domains, the idea should still be clear...
void processResource(Resource* resource)
{ /* ... */ }
void processClient(Client* c)
{
processResource(&c->a);
// ...
processResource(&c->g);
}
void processDomain(Domain* d)
{
processClient(&d->a);
// ...
processClient(&d->g);
}
As already mentioned: it is the other extreme. You might maintain arrays within your structs, such that you might iterate over as:
void processDomain(Domain* d)
{
for(size_t i = 0; i < sizeof(d->clients)/sizeof(*d->clients); ++i)
{
processResource(d->clients + i);
}
}
Or have some lower n-dimensional arrays within some of the structs. Any combination would do the trick, all up to you, whatever you consider most appropriate...
You could even extend to dynamic arrays:
typedef struct
{
Resource* resources;
size_t count;
} Client;
if you consider managing variable numbers of sub-elements useful.
If all this is 'better' than the original 4D-array? Mainly a matter of taste, I'd say, unless perhaps a better chance of reusability especially of the lower nested structs, but current use-case appears too specific for this really applying here.

Related

How to expose variable sized arrays inside C struct in swig?

I'm struggling for a few days now to find a solution to wrap a C struct containing multiple variable-sized int arrays (stored as pointers) in swig.
Suppose the following minimal example:
typedef struct {
size_t length;
int *a;
int *b;
} mystruct;
where both a and b are pointers to int arrays allocated somewhere in C. The size of both arrays is stored in the length member.
Now, what I would really like to have is two-fold:
access to a and b members in objects of type mystruct should be safe, i.e. exceptions should be thrown if index is out-of-bounds.
the data in a and b must not be copied-over into a python list or tuple but I want to provide __getitem__ methods instead. The reason for that is that the actual struct consists of many such arrays and they get really huge and I don't want to waste any memory by duplicating them.
I've seen examples how to accomplish this with fixed-sized arrays by writing wrapper classes and templates for each member that internally store the size/length of each array individually, e.g.: SWIG interfacing C library to Python (Creating 'iterable' Python data type from C 'sequence' struct) and SWIG/python array inside structure.
However, I assume once I would wrap a and b into a class to enable them to be extended with __getitem__ methods, I won't have access to the length member of mystruct, i.e. the 'container' of a and b.
One thing I tried without success was to write explicit _get and _set methods
typedef struct {
size_t length;
} mystruct;
%extend mystruct {
int *a;
};
%{
int *mystruct_a_get(mystruct *s) {
return mx->a;
}
int *mystruct_b_get(mystruct *s) {
return mx->b;
}
...
%}
But here, the entire arrays a and b would be returned without any control of the maximum index...
My target languages are Python and Perl 5, so I guess one could start writing complicated typemaps for each language. I've done that before for other wrappers and hope there is a more generic solution to my situation that involves only C++ wrapper classes and such.
Any help or idea is appreciated!
Edit for possible solution
So, I couldn't let it go and came up with the following (simplified) solution that more or less combines the solutions I already saw elsewhere. The idea was to redundantly store the array lengths for each of the wrapped arrays:
%{
/* wrapper for variable sized arrays */
typedef struct {
size_t length;
int *data;
} var_array_int;
/* convenience constructor for variable sized array wrapper */
var_array_int *
var_array_int_new(size_t length,
int *data)
{
var_array_int *a = (var_array_int *)malloc(sizeof(var_array_int));
a->length = length;
a->data = data;
return a;
}
/* actual structure I want to wrap */
typedef struct {
size_t length;
int *a;
int *b;
} mystruct;
%}
/* hide all struct members in scripting language */
typedef struct {} var_array_int;
typedef struct {} mystruct;
/* extend variable sized arrays with __len__ and __getitem__ */
%extend var_array_int {
size_t __len__() const {
return $self->length;
}
const int __getitem__(int i) const throw(std::out_of_range) {
if ((i < 0) ||
(i >= $self->length))
throw std::out_of_range("Index out of bounds");
return $self->data[i];
}
};
/* add read-only variable sized array members to container struct */
%extend mystruct {
var_array_int *const a;
var_array_int *const b;
};
/* implement explict _get() methods for the variable sized array members */
%{
var_array_int *
mystruct_a_get(mystruct *s)
{
return var_array_int_new(s->length, s->a);
}
var_array_int *
mystruct_b_get(mystruct *s)
{
return var_array_int_new(s->length, s->b);
}
%}
The above solution only provides read access to the variable sized arrays and does not include any NULL checks for the wrapped int * pointers. My actual solution of course does that and also makes use of templates to wrap variable sized arrays of different types. But I refrained from showing that here for the sake of clarity.
I wonder if there is an easier way to do the above. Also the solution only seems to work in Python so far. Implementing something similar for Perl 5 already gives me a headache.

C same structure different size

My question is related to this one :
c define arrays in struct with different sizes
However, I do NOT want to use dynamic allocation (embedded target).
Problem recap :
In C, I want to have two versions of the same structure, each one with a different size for its static arrays.
Both the structures will be used by the same functions through pointer parameter.
typedef struct {
short isLarge; //set 0 at initialization
short array[SIZE_A];
//more arrays
} doc_t;
typedef struct {
short isLarge; //set 1 at initialization
short array[SIZE_B];
//more arrays
} doc_large_t;
void function( doc_t* document ) {
if ( document->isLarge ) {
//change document into doc_large_t* [1]
}
//common code for both doc_t and doc_large_t
}
Questions :
(1) The above description needs a way to dynamically cast the pointer doc_t* pointer to doc_large_t* document [1]. Is that possible ? How ?
(2) An other solution i came with is to have a common header data part for both structure, including not only the isLarge flag, but also the pointers to the following static arrays. How ugly is that ?
(3) Also, do you have a good trick or workarround I could use ?
EDIT :
More context :
My application is a path finding on an embedded MCU.
I have geometrical objects, like polygons. Polygons can describe simple rectangular obstacles, as well as more complex shapes (such as the accessible area).
Complex polygons can have a huge amount of vertices, but are in small quantity. Simple polygons are very common.
Both will use the same algorithms.
I know in advance which polygon will need more vertices.
What I am trying to do is to optimize working memory to make it fit into the MCU. (i.e. small shapes get small arrays; complex ones get large arrays)
Idea similar to what you mentioned in your question already (pointers to arrays), but with only one single pointer:
typedef struct
{
short array[SIZE_B - SIZE_A];
// more arrays alike...
} Extension;
typedef struct
{
short array[SIZE_A];
//more arrays (all the small ones!)
Extension* extraData;
} doc_t;
If extraData is NULL, you have a small polygone, otherwise, you find the additional data in the struct referenced. Admitted, iterating over all values for large polygons gets a little nasty...
If you can use global arrays of predefined size for each object type (as Dominic Gibson proposed - a good proposition, by the way), you could spare the isLarge flag by replacing it with a function:
int isLarge(void* ptr)
{
return
(uintptr_t)globalLargeArray <= (uintptr_t)ptr
&&
(uintptr_t)ptr < (uintptr_t)globalLargeArray + sizeof(globalLargeArray);
}
Of course, all polygons (in above case: the large ones at least) would have to live in this array to make it work. If you create at least one dynamically or otherwise elsewhere (stack, another global variable) - we are out...
Create the arrays globally and use a pointer pointig to the big or small array.
You should try to keep a single structure and for the different array sizes put them in an union. I don't know whether the following structure would make sense to your case.
typedef struct {
short isLarge; //manually set to 0 or 1 after creating structure
//and accordingly initialize the arrays in below union
union my_varying_arrays {
short array_A[SIZE_A];
short array_B[SIZE_B];
};
//more arrays
} doc_t;
If isLarge is 0, set the value for array_A array and if 1 set the value for array array_B.
You can do this is the data is const by using a void * to the specific array.
Then you just cast the void * to what you need it to be depending on the attributes in the structure.
It becomes more complicated when you need the structures in runtime.
Especially on embedded targets.
typedef struct {
short size;
void *array;
} doc_t;
Where array points to a memory block allocated by the memory manager.
You now have to decide whether to use C standard malloc or use some pooled memory system based on the largest block size.
An example would be ChibiOS Memory pools.
If you are allocating and freeing variable sized memory blocks at random you risk memory fragmentation.
If you allocate incrementally you don't have to worry about much about memory. Just create one large block and keep track of where you are. A bit like a stack.
After the edit, I think the best thing you can do is to profile your needs defining max simple and complex polygons your target can manage and then declare a pool of simplex and common polygons, like:
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#define MAX_COMPLEX 16
#define MAX_SIMPLE 16
uint16_t g_Simple_Poly_set[MAX_COMPLEX][SIZE_A];
uint16_t g_Complex_Poly_set[MAX_COMPLEX][SIZE_B];
uint16_t g_Simple_Poly_used = 0;
uint16_t g_Complex_Poly_used = 0;
struct poly
{
bool isLarge;
uint16_t *vetexes;
};
bool create_poly_simple (struct poly *p)
{
bool retVal = false; // default: not more space for poly
if (g_Simple_Poly_used < MAX_SIMPLE)
{
p->isLarge = false;
p->vetexes = &g_Simple_Poly_set[g_Simple_Poly_used][0];
g_Simple_Poly_used++;
retVal = true;
}
return retVal;
}
bool create_poly_compleX (struct poly *p)
{
bool retVal = false; // default: not more space for poly
if (g_Complex_Poly_used < MAX_COMPLEX)
{
p->isLarge = true;
p->vetexes = &g_Complex_Poly_set[g_Complex_Poly_used][0];
g_Complex_Poly_used++;
retVal = true;
}
return retVal;
}
void your_stuff_with_poly ( struct poly *p)
{
uint32_t poly_size = (p->isLarge == false) ? SIZE_A : SIZE_B;
// your stuff with the correct size
}
This is a simple implementation designed for a static "instantiation" of structs. You can also enhance the code with a create/destroy function that trace which array into pool is free to be used.
Your number 2 solution is the right idea. It's unclear to me why you think that is ugly. Maybe this beautiful implementation will change your mind.
You can implement single inheritance is C by placing the base structure as the first member of the inheriting structure. Then inheriting objects can be referenced with a pointer to the base type.
typedef struct {
short doc_type;
short *array_ptr;
// more array pointers
} doc_base_t;
typedef struct {
doc_base_t base; // base.doc_type set 0 at initialization
short array[SIZE_A]; // base.array_ptr initialized to point here
//more arrays
} doc_small_t;
typedef struct {
doc_base_t base; // base.doc_type set 1 at initialization
short array[SIZE_B]; // base.array_ptr initialized to point here
//more arrays
} doc_large_t;
void function( doc_base_t* document ) {
if ( document->doc_type == 1) {
// array size is large
} else {
// array size is small
}
//common code referencing arrays through doc_base_t->array_ptr
}
The array_ptr member in doc_base_t isn't necessary for the inheritance mechanism. But I added that specifically for the "common code" portion of your function. If doc_base_t didn't include the array_ptr then you could cast the generic document to either adoc_small_t or doc_large_t type based upon the base_type value. But then you might need a different implementation for each inherited type. By adding the array_ptr member to doc_base_t I suspect you could write a common implementation for all inherited types.
So you will statically declare all your instances of doc_small_t and doc_large_t. And you'll initialize both the base.doc_type and base.array_ptr members when initializing each object. Then you will cast both types of objects to doc_base_t before calling function. (Or pass the address of the base member, which results in the same pointer value.)
Updated example:
static doc_small_t doc_small_instances[NUM_SMALL_INSTANCES];
static doc_large_t doc_large_instances[NUM_LARGE_INSTANCES];
// DocInit must be called once at startup to initialize all the instances.
void DocInit()
{
int index;
for (index = 0; index < NUM_SMALL_INSTANCES; index++)
{
doc_small_instances[index].base.doc_type = SMALL;
doc_small_instances[index].base.array_ptr = doc_small_instances[index].array;
}
for (index = 0; index < NUM_LARGE_INSTANCES; index++)
{
doc_large_instances[index].base.doc_type = LARGE;
doc_large_instances[index].base.array_ptr = doc_large_instances[index].array;
}
}
// DocProcess processes one doc, large or small.
void DocProcess(doc_base_t *document)
{
int index;
short *array_member_ptr = document->array_ptr;
int array_size = SMALL;
if (document->doc_type == LARGE)
{
array_size = LARGE;
}
for (index = 0; index < array_size; index++)
{
// Application specific processing of *array_member_ptr goes here.
array_member_ptr++;
}
}
// ProcessAllDocs processes all large and small docs.
void ProcessAllDocs(void)
{
int index;
for (index = 0; index < NUM_SMALL_INSTANCES; index++)
{
DocProcess(&doc_small_instances[index].base);
}
for (index = 0; index < NUM_LARGE_INSTANCES; index++)
{
DocProcess(&doc_large_instances[index].base);
}
}
It's easy with malloc() or similar dynamic allocation methods. Just use a flexible array member:
typedef struct {
short isLarge; //set 0 at initialization
.
.
.
short array[SIZE_A];
short largeArray[];
} doc_t;
To allocate a "small structure":
doc_t *small = malloc( sizeof( *small ) );
small->isLarge = 0;
To allocate a "large structure":
doc_t *large = malloc( sizeof( *large ) + ( SIZE_B - SIZE_A ) * sizeof( large->largeArray[ 0 ] );
large->isLarge = 1;
Note that you must keep the largeArray element last, which means that the array element must be next-to-last for this to work.
Depending on how you do your own allocation, this may or may not be applicable.
(It's also a bit of a hack, since it depends on being able to access data in largeArray by using an index of SIZE_A or greater on array. That's accessing an object outside its bounds...)

union types and flexible array member

I have a question about the flexible-length arrays in C structures (http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html).
typedef struct {
size_t N;
int elems[];
} A_t;
Now the general approach is quite obvious,
A_t * a = malloc(sizeof(A_t) + sizeof(int) * N)
a->N = N;
....
Now this seems to be awkward when trying to incorporate stuff into other structs or stack-based allocation. So something like the following snipet is bound to fail for N!=0
struct {
A_t a;
A_t b; /// !!!!!
double c; /// !!!!!
};
Now I think it should be possible to allow for usages like this by defining another type
typedef struct {
size_t N;
int elems[5];
} A_5_t;
struct {
A_5_t a;
A_5_t b;
double c; // should work here now.
} mystruct;
and then use it as if it were an A_t structure. When calling a function void foo(A_t * arg1);, one would need to use something like foo((A_t*) (&mystruct.b)). Which -- to me -- appears to be a bit clumsy. I therefore wonder whether there is a better way to do this. I wonder whether one could employ a union type for this somehow?
I am asking this question, because the flexible-length array makes it possible to have data in one piece in the structure, therefore one can copy a struct with a single command instead of having to worry about deep and shallow copies, etc.
You have a mult-layered question.
In this one example:
struct {
A_t b;
double c; /// fails
};
I would try:
struct {
double c;
A_t b;
};
Always place the variable portion of a struct at the end. Note, I don't use GCC, so try this, it might/maybe work.
To follow-up on a requirement given by #wirrbel, the following struct is NOT variable length, but it does define and provide access to a variable length array of integers.
typedef struct {
size_t N;
int *(elems[]); // parens to ensure a pointer to an array
} A_t;
A_t *a = malloc //etc.
a->elems = malloc(sizeof(int) * N);
In this fashion several A_t structures can be included in a more general structure.
No, in general your two struct, A_t and A_5_t, are not interchangeable. The reason is that the version with the flexible array can have different padding in front of the elems field than versions with a fixed field length.
Whether or not your compiler implements a different padding or not, you can test by using the offsetof macro. But even if the offsets are the same for your particular compiler and platform, you'd better not rely on that if you want portable code.
I have figured it out now (the solution has actually been descibed in the gnu documentation as provided above). By appending an array declaration after the struct declaration, one does create a contiguous memory range that is directly adjacent to the "empty" flexible array. Therefore b.A.elems[i] is referencing the same data as b.elems_[i].
It is probably advisable to choose an identifier that tells you that the memory of this array is actually belonging to the structure. at least thats how I would use it then.
typedef struct {
size_t N;
double elems[];
} A_t;
typedef struct {
A_t a;
double elems_[4];
} B_t;
void foo(A_t * arg1) {
for (size_t i=0; i < arg1->N; ++i) {
printf("%f\n", arg1->elems[i]);
}
}
int main(int argc, char *argv[]) {
B_t b;
b.a.N = 4;
for (int i=0; i < 4; ++i) {
b.elems_[i] = 12.4;
}
foo(&b.a);
}

C generic type as function argument input

So I have two different structs in which all the properties that I will be accessing will be the same. and I also have a function, who's argument, i want to be able to accept either of the two. Example:
typedef struct{
int whatnot = 14;
int thing[11];
} TH_CONFIG;
typedef struct{
int whatnot = 3;
int thing[5];
} TH_CONFIG_2;
*_CONFIG var;
void fun(*_CONFIG input)
{
input.whatnot = 5;
}
int main(){
fun(var);
}
I may have an inkling that I should use void as the type from that I could typecast or something?, but my searching has only yielded things about function pointers, templates, and C#.
EDIT: *_CONFIG is not meant to be syntactically correct, its signifying that I don't know what to do there, but its supposed to be the _CONFIG type
Possible solutions.
Just use an array of length 11 for both of them. Did you really run out of those last 6 bytes on your OS?
Make it a dynamic array.
Just write in assembly, you clearly don't care about C's higher-level-ness.
Use a language like C++ that supports templates or polymorphism.
Just pass in the arguments of the struct you care about.
void fun(int* whatnot) {
*whatnot = 5;
}
int main() {
fun(&myStruct.whatnot);
return 0;
}
Factor into a quasi-OO design.
struct {
int whatnot;
} typedef Common;
struct TH_CONFIG_1 {
Common common;
int thing[11];
};
struct TH_CONFIG_2 {
Common common;
int thing[5];
}
But if you insist...
void fun(void* input) {
( (int)(*input) ) = 5;
}
or...
void fun(void* input) {
( (TH_CONFIG*) input)->whatnot = 5; // may have been a TH_CONFIG_2, but who cares?
}
Note: this would not pass code review at any C shop.
You can use any pointer type and cast it.
If all the properties you're accessing are the same, I'm guessing one's an extension of the other (since the properties need to have the same offset from the beginning of the struct). In that case you may want to use this pattern:
struct base {
int foo;
char **strings;
};
struct extended {
struct base super;
double other_stuff;
};
Since super is at the start of struct extended, you can cast a struct extended * to struct base * without problems. Of course, you could do that by repeating the same fields in the beginning of struct extended instead, but then you're repeating yourself.

Is there any way to pass a structure type to a c function

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")
}

Resources