xcdev
xcdev

Reputation: 37

C: Array of memory addresses?

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

Answers (2)

4386427
4386427

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

0___________
0___________

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

Related Questions