C语言 在const表达式中声明指向结构体的指针



我是C的新手,还不能自由地浏览我的程序内存。无论如何,我正在创建一个静态内存数据类型(gc_menu),它应该包含一个指针,指向在执行时创建的结构(mcl_items)。

为了简单起见,mcl_items结构有一个虚拟方法(push),它将在gc_menu_add_item内部运行,并分配给gc_menu静态空间。push保存菜单项名称(字母)和方法到mcl_item虚拟对象。

mcl_items.hcode:

[...]
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.ccode:

[...]
#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.hcode:

#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.ccode:

static void gc_menu_add_item(char c, void (*method)) {
fprintf(stderr, "GC_Menu: Passing an new item..");
fprintf(stderr, "length = %in", 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

调用gc_menu.add_item后出现分段故障,gc_menu.items->size= 72,而不是new_mcl_items定义中定义的0。

main.ccode:

gc_menu.add_item('q', xw->end(xw));
GC_Menu: Passing an new item..length = 72
[1]    66021 segmentation fault (core dumped)  ./3D_scean

我做错了什么?为什么有这样一个奇怪的数据写入我的gc_menu.items的实例?

您已经将gc_menu.items初始化为new_mcl_items,即指向函数new_mcl_items的指针(它应该给您一个警告,因为它是mcl_items *(*)(void)类型而不是mcl_items *)。

看起来您想要的实际上是调用函数new_mcl_items()并将gc_menu.items设置为new_mcl_items()返回的值。你不能用初始化器这样做;全局或static对象的初始化式必须在编译或链接时已知。标准C语言没有"构造函数">

因此,您必须从gc_menu的声明和定义中删除const,并在main(或main调用的某些函数等)中添加代码,以便在运行时初始化gc_menu.items

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或者随便你怎么称呼它

int main(void) {
// ...
gc_menu.items = new_mcl_items();
// ...
}

最新更新