pointers-memory · advanced · ~15 min
Implement dynamic dispatch and object-oriented polymorphism in C using vtables and self pointers.
Object-oriented languages implement dynamic dispatch using virtual method tables (vtables). In C, object polymorphism is achieved manually by storing a pointer to a vtable struct of function pointers inside a base structure.
Implement:
struct shape_vtable {
int (*area)(const void *self);
int (*perimeter)(const void *self);
};
struct shape {
const struct shape_vtable *vptr;
};
struct rect {
struct shape base;
int width;
int height;
};
void rect_init(struct rect *r, int width, int height);
int shape_area(const struct shape *s);
int shape_perimeter(const struct shape *s);
rect that compute:area: width * heightperimeter: 2 * (width + height)struct shape_vtable rect_vtable.rect_init: set r->base.vptr = &rect_vtable, r->width = width, and r->height = height.shape_area: dispatch s->vptr->area(s). If s == NULL or vptr == NULL, return 0.shape_perimeter: dispatch s->vptr->perimeter(s). If s == NULL or vptr == NULL, return 0.r: pointer to struct rect; width, height: dimensions; s: generic struct shape pointer.
Returns computed area or perimeter via vtable dispatch.
C11 freestanding. Vtable polymorphism pattern.
#include <stddef.h>
/* The harness provides:
struct shape_vtable {
int (*area)(const void *self);
int (*perimeter)(const void *self);
};
struct shape {
const struct shape_vtable *vptr;
};
struct rect {
struct shape base;
int width;
int height;
};
*/
void rect_init(struct rect *r, int width, int height) {
(void)r; (void)width; (void)height;
}
int shape_area(const struct shape *s) {
(void)s;
return 0;
}
int shape_perimeter(const struct shape *s) {
(void)s;
return 0;
}
Not casting self back to struct rect* inside the method implementations; dereferencing NULL vptr.
NULL shape returns 0; zero width/height returns 0 area; dispatching through base shape pointer.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.