sorakun
sorakun

Reputation: 23

How to handle different data types, in one array, in C

I would like to simulate the object oriented programming, so in C++, let's consider the following C code:

typedef struct tAnimal{
   char * name;
   int age;
}tAnimal;

typedef struct tAnimal2{
   char * name;
   int age;
   float size;
}tAnimal2;   

In C++ you can create a table of different objects which are inherited from the same class. I would like to do the same in C, let's consider the following code:

tAnimal ** tab;
tab = malloc(sizeof(tAnimal*)*2);
tab[0] = malloc(sizeof(tAnimal));
tab[1] = malloc(sizeof(tAnimal2));

Notice that the allocation works because malloc returns a void pointer, and C does not require casting. But I still have no access to the size field, because the type of tab elements is tAnimal after all.

Is there anyway to fix this?, I would like to stay away from void ** pointers.

Upvotes: 2

Views: 3950

Answers (3)

Dima Chubarov
Dima Chubarov

Reputation: 17179

In order to access the size field in tab[1] you can cast the pointer to a tAnimal2 pointer.

 tAnimal2* panimal2 = (tAnimal2*) tab[1];
 panimal2->size = 1.0;

However this practice is prone to data corruption since you will need a method to ensure that the element of the table you cast to tAnimal2 is indeed an instance of tAnimal2. You could use an additional type field as Joachim Pileborg suggests to check the type of the object.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409482

In C it's common to use a structure with a type-flag, and a union of the data:

typedef enum
{
    Animal1,
    Animal2
} AnimalType;

struct Animal
{
    AnimalType type;

    union
    {
        tAnimal  animal;
        tAnimal2 animal2;
    };
};

Now you can create an array of the Animal structure.

Upvotes: 3

fscan
fscan

Reputation: 433

If you want to access the size field you have to cast your pointer to tAnimal2. Note, the same would be true for C++.

You can kind of simulate inheritance by embedding the first struct at the beginning of the second:

struct tAnimal{
   char * name;
   int age;
};

struct tAnimal2{
  struct tAnimal parent;

  float size;
};

Upvotes: 0

Related Questions