I have two different structures and and two const look up tables as below
typedef const struct
{
unsigned int num;
unsigned char name[100];
unsigned int value1;
unsigned int value2;
unsigned int value3;
}st_Table1;
typedef const struct
{
unsigned int num;
unsigned char name[100];
}st_Table2;
st_Table1 stTable1[] =
{
{ 1, "Name1", 12, 13, 14 },
{ 2, "Name2", 22, 23, 24 },
{ 3, "Name3", 32, 33, 34 },
{ 4, "Name4", 42, 43, 44 }
};
st_Table2 stTable2[] =
{ 1, "India1" },
{ 2, "India2" },
{ 3, "India3" }
};
Could it be possible to have single pointer that can point to both the lookup tables stTable1
and stTable2
?
When I have to make the decision for selection of either of the two tables we can assign the address of the table (either of).
But after that I wanted to use the single pointer in the remaining code.
Please reply for any logic ... hint ... clue
Arvind
well you could create a struct
typedef struct _tableChoice
{
st_Table1* table1;
st_Table2* table2;
} tableChoice_t,*p_tableChoice_t;
then you could pass along an argument of type p_tableChoice_t
until you need to specifically access one of the tables. If you need to decide during runtime what pointer to use you would need to have both pointers available at the decision point.
You can get the same effect as the casts other have suggested with a union as well
union table_ptr {
st_Table1*table1;
st_Table2*table2;
} my_table_ptr;
and just assign/access the desired member.
You could create a void pointer:
void * ptr;
Like any other pointer this can point to any memory address but it doesn't specify what type of data is stored there, so you could dereference it but you'd have to depend on your own knowledge of the structures to access different elements etc.. If you have some other flag indicating what type of record it's pointing to, you could cast it back to the required type of pointer.
Given that both of your structs have common ground you'd be better off just using the first one and accepting the small overhead on memory for instances where you only need num
and name
. I hate software bloat and wasted memory, but you're talking about an extra 12 bytes (on most platforms) for records where value1-3
are not needed, so unless we're talking about billions of records chances are the extra code required to deal with more will consume more memory than the wasted space.
Another option could be a union, where you lose 12 bytes from name
for records of the second type so that all records take up the same amount of space, though of course compiler padding my make a difference on some platforms.
You may want to follow a similar pattern to the sockaddr
family of structures. In that setup, all of the structures must have the same size and the same initial layout, something like:
typedef const struct
{
unsigned int num;
unsigned char name[100];
char buffer_[sizeof(unsigned int) * 3];
} st_TableBase;
typedef const struct
{
unsigned int num;
unsigned char name[100];
unsigned int value1;
unsigned int value2;
unsigned int value3;
} st_Table1;
typedef const struct
{
unsigned int num;
unsigned char name[100];
char buffer_[sizeof(unsigned int) * 3];
} st_Table2;
With this structure, you would normally maintain a pointer of type st_TableBase
. With this pointer you'll be able to access the num or name members directly, since all of the types have a consistent initial layout. If you need to access additional fields, you can cast st_TableBase
to one of the "derived" types.
For more information on the sockaddr
structures see http://www.retran.com/beej/sockaddr_inman.html.
It's impossible. A pointer must know its own range in order to read and write correctly during runtime, or you can do nothing with it. If you don't know whether it's table1 or table2, how can you write code to read it? (what type is the value
in value = *pointer;
?) On the other hand, if you do know it's a table1/table2, why not use a pointer of specific type?
OR (if you insist)
Just use st_Table1
as st_Table2
and accept the waste of memory (3*sizeof(unsigned int) for each record). It won't be a big waste unless you have billions of record. You don't want to hold billions of data record by C structure.
OR (well, you hate waste)
typedef struct
{
int num;
char name[100];
int *value;
}st_table;
well, you have a unified structure now. Allocate value
during runtime if you need it (value = (int *)malloc(3 * sizeof(int));
). Don't forget the NULL check before you read value
.