Inheritance in C
I am playing with the implementation of inheritance in C. I wrote the following two options. Method 1 fails during program startup, but method 2 works fine. What am I doing wrong in method 1?
Method 1:
#include<stdio.h>
#include<stdlib.h>
typedef struct base_class
{
int a;
}Base;
typedef struct derived_class
{
int b;
Base *base_ptr;
}Derived;
int main(void){
Derived *der_ptr;
der_ptr = (Derived *)malloc(sizeof(Derived));
der_ptr->b = 5;
der_ptr->base_ptr->a=10;
printf("%d %d",der_ptr->b,der_ptr->base_ptr->a);
}
Method 2:
#include<stdio.h>
#include<stdlib.h>
typedef struct base_class
{
int a;
}Base;
typedef struct derived_class
{
int b;
Base base_ptr;
}Derived;
int main(void){
Derived *der_ptr;
der_ptr = (Derived *)malloc(sizeof(Derived));
der_ptr->b = 5;
der_ptr->base_ptr.a=10;
printf("%d %d",der_ptr->b,der_ptr->base_ptr.a);
}
source to share
There is nothing wrong with Method 2, but it depends on what you are trying to achieve.
However, in method 1, you never allocate space for the pointer Base *base_ptr
and then you play it out, which is why your program crashes.
This and notice that I removed the cast because when needed in C ++ it is not needed in c
der_ptr = malloc(sizeof(Derived));
allocates space for one int
and one pointer, so sizeof(Derived) = sizeof(int) + sizeof(void *)
if you want to access an element a
base_ptr
, you need to allocate space for it, after allocating for der_ptr
and checking that the allocation was successful, you then allocate an element for it base_ptr
like this
der_ptr->base_ptr = malloc(sizeof(Base));
and then you can access the item base_ptr
a
.
Also, note that unlike the operator new
in C ++, which performs some operations with exceptional handling when not present, in c you have to check that you malloc
returned a valid pointer, it returns on error NULL
.
So your method 1 should work like this
#include<stdio.h>
#include<stdlib.h>
typedef struct base_class
{
int a;
} Base;
/*
typedef struct derived_class
{
int b;
Base *base_ptr;
} Derived;
*/
/* the order matters, this way you can cast Derived to Base */
typedef struct derived_class
{
Base *base_ptr;
int b;
} Derived;
int main(void) {
Derived *der_ptr;
der_ptr = malloc(sizeof(Derived));
if (der_ptr == NULL)
return 1;
der_ptr->b = 5;
der_ptr->base_ptr = malloc(sizeof(Base));
if (der_ptr->base_ptr == NULL)
{
free(der_ptr);
return 2;
}
der_ptr->base_ptr->a = 10;
printf("%d %d", der_ptr->b, der_ptr->base_ptr->a);
free(der_ptr->base_ptr);
free(der_ptr);
}
and note that you can now cast Derived *
in Base *
when members are in that order.
source to share
As others have already pointed out, you are not allocating memory for Base, so method 1 will result in random access to some location in memory.
If you are interested in implementing OO and higher-level programming interfaces in C, I recommend taking a close look at libCello , you will be surprised at the expressiveness.
source to share