I am new to C and can't yet freely navigate trough my program memory. Anyways, I am creating a static memory data type (gc_menu
) that should hold a pointer to created at execution time structure (mcl_items
).
For simplicity mcl_items
structure have one virtual method (push
) that is going to be run inside of gc_menu_add_item
and also assigned to the gc_menu
static space. push
saves an menu item name (letter) and method to mcl_item
virtual object.
mcl_items.h
code:
[...]
typedef struct Items_t {
int8_t size;
char names[64];
void (*methods[64])();
// Interface
void (*push)(struct Items_t *self, char c, void (*method)());
}mcl_items;
mcl_items *new_mcl_items();
void mcl_items_push(mcl_items *self, char c, void (*method)());
mcl_items.c
code:
[...]
#include "mcl_items.h"
mcl_items *new_mcl_items() {
fprintf(stderr, "MCL_Items: Generating a new set of mcl_items..");
// Build a virtual object
mcl_items *items = calloc(1, sizeof(struct Items_t));
items->push = mcl_items_push;
// Set data
items->size = 0;
return items;
}
void mcl_items_push(mcl_items *self, char c, void (*method)()) {
fprintf(stderr, "MCL_Items: pushing a new item..");
self->names[self->size] = c;
self->methods[self->size] = method;
self->size ++;
}
gc_menu.h
code:
#include "items.h"
typedef struct {
// Interface
void (*add_item)(char c, void (*method)());
// Data
mcl_items *items;
}__gc_menu;
extern __gc_menu const gc_menu;
gc_menu.c
code:
static void gc_menu_add_item(char c, void (*method)) {
fprintf(stderr, "GC_Menu: Passing an new item..");
fprintf(stderr, "length = %i\n", gc_menu.items->size);
gc_menu.items->push(gc_menu.items, c, method);
}
__gc_menu const gc_menu = {gc_menu_add_item, // Virtual methods
new_mcl_items}; // Data
After callng gc_menu.add_item
the segmentation fault occurs and gc_menu.items->size
is equal to 72, not 0 as is defined in the definition of new_mcl_items
.
main.c
code:
gc_menu.add_item('q', xw->end(xw));
GC_Menu: Passing an new item..length = 72
[1] 66021 segmentation fault (core dumped) ./3D_scean
So what am I doing wrong? Why is there such a weird data written to instances of my gc_menu.items
?
You've initialized gc_menu.items
to new_mcl_items
, i.e. a pointer to the function new_mcl_items
(which should give you a warning since it is of type mcl_items *(*)(void)
and not mcl_items *
).
It looks like what you want is to actually call the function new_mcl_items()
and set gc_menu.items
to the value that new_mcl_items()
returns. You can't do this with an initializer; initializers of global or static
objects must be known at compile or link time. Standard C doesn't have "constructors".
So you'll have to remove the const
from the declaration and definition of gc_menu
, and add code to main
(or some function called by main
, etc) to initialize gc_menu.items
at run time.
gc_menu.h
:
extern __gc_menu gc_menu;
gc_menu.c
:
__gc_menu gc_menu = {
gc_menu_add_item,
NULL // or whatever else you like
};
main.c
or whatever you have called it:
int main(void) {
// ...
gc_menu.items = new_mcl_items();
// ...
}