Reputation: 37
I'm trying to make a sort of container for multiple different structs. Unfortunately C only allows type specific arrays, meaning I'd have to make a different array for each type of struct.
The current solution I came up with is a container that holds memory addresses. This way the program can just pass the memory address of one of the elements to a function.
Currently the only code I have is a failed attempt using void pointers (not really familiar with pointers and memory addresses yet unfortunately)
The following is my test code I was writing to try and understand how this stuff works:
void* arr[10]={};
int len=0;
int n[5]={1,2,3,4,5};
for (int i=0;i<5;i++) { //add pointers nums in n to arr
arr[i]=(void*)(&n[i]);
len++;
}
for (int i=0;i<len;i++) { //print contents of arr
printf("%p\n", (void*)arr[i]);
printf("\t%d\n", arr[i]); //trying to print actual value (eg. 2 for index 2) but not really sure how to...
}
Thanks!
Upvotes: 0
Views: 1016
Reputation: 44284
Your approach is correct but there is some stuff missing...
In C any object pointer can be converted to a void-pointer and back to a pointer of the original type. So an int-pointer can be converted to a void-pointer an back to an int-pointer. And a float-pointer can be converted to a void-pointer an back to an float-pointer.
So using an array of void-pointers to store pointers to different object types is a fine approach.
But... in order to convert the void-pointer back to the original type, you need to know what the original type was. If you just saves the void-pointer, you don't have that information.
Instead consider something like:
struct gp
{
void* p;
unsigned type_tag;
}
#define INT_TYPE 0
#define FLOAT_TYPE 1
and use it like:
struct gp arr[2];
int n = 42;
float f = 42.42;
arr[0].p = &n;
arr[0].type_tag = INT_TYPE;
arr[1].p = &f;
arr[1].type_tag = FLOAT_TYPE;
for (int i=0; i < 2; ++i)
{
if (arr[i].type_tag == INT_TYPE)
{
int* p = (int*)arr[i].p; // Cast void-pointer back to int-pointer
printf("%d\n", *p); // Get int-value using *p, i.e. dereference the pointer
}
else if (arr[i].type_tag == FLOAT_TYPE)
{
int* p = (float*)arr[i].p; // Cast void-pointer back to float-pointer
printf("%f\n", *p); // Get float-value using *p, i.e. dereference the pointer
}
}
Upvotes: 1
Reputation: 67546
You need to derefence the pointer stored in the array. You also need to cast it to the original type of the referenced objects.
printf("\t%d\n", *(int *)arr[i]);
Upvotes: 1