Is it possible to iterate of a C struct, where all members are of same type, using a pointer. Here's some sample code that does not compile:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int mem1 ;
int mem2 ;
int mem3 ;
int mem4 ;
} foo ;
void my_func( foo* data )
{
int i ;
int* tmp = data ; // This line is the problem
for( i = 0; i < 4; ++i )
{
++tmp ;
printf( "%d\n", *tmp ) ;
}
}
int main()
{
foo my_foo ;
//
my_foo.mem1 = 0 ;
my_foo.mem2 = 1 ;
my_foo.mem3 = 2 ;
my_foo.mem4 = 3 ;
//
my_func( &my_foo ) ;
return 0 ;
}
The members of foo should be aligned in memory to be one after another, assuming your compiler/kernel does not try to provide stack protection for buffer overflow.
So my question is:
How would I iterate over members of a C struct that are of the same type.
Most of the attempts using a union with an array are prone to failure. They stand a decent chance of working as long as you only use int's, but for other, especially smaller, types, they're likely to fail fairly frequently because the compiler can (and especially with smaller types often will) add padding between members of a struct
, but is not allowed to do so with elements of an array).
C does, however, have an offsetof()
macro that you can use. It yields the offset of an item in a struct
, so you can create an array of offsets, then (with a bit of care in casting) you can add that offset to the address of the struct to get the address of the member. The care in casting is because the offset is in bytes, so you need to cast the address of the struct
to char *
, then add the offset, then cast the result to the type of the member (int
in your case).
From the language point of view: you can't. data members of the struct are not... er.. "iteratible" in C, regardless of whether they are of the same type or of different types.
Use an array instead of a bunch of independent members.
The easiest way would be to create a union, one part which contains each member individually and one part which contains an array. I'm not sure if platform-dependent padding might interfere with the alignment.
You can also use an unnamed union/struct:
struct foo {
union {
struct {
int mem1;
int mem2;
int mem3;
int mem4;
};
int elements[4];
};
};
foo thefoo;
for (int i = 0; i < 4; ++i) {
thefoo.elements[i] = i;
}
This might not work on some compilers, int this case you'll have to explicitily name the union and struct inside foo
,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With