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);
}

      

+3


source to share


3 answers


Method 1 fails because of this line of code:

der_ptr->base_ptr->a=10;

      



Ask yourself: what is the meaning der_ptr->base_ptr

?

+5


source


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.

+4


source


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.

+1


source







All Articles