在 const 表达式中声明一个指向结构的指针
Declare a pointer to structure in const expression
我是 C 的新手,还不能自由浏览我的程序内存。无论如何,我正在创建一个静态内存数据类型(gc_menu
),它应该包含一个指向在执行时创建的结构(mcl_items
)的指针。
为简单起见,mcl_items
结构有一个虚拟方法 (push
),它将在 gc_menu_add_item
内部 运行 并分配给 gc_menu
静态 space。 push
将菜单项名称(字母)和方法保存到 mcl_item
虚拟对象。
mcl_items.h
代码:
[...]
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
代码:
[...]
#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
代码:
#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
代码:
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
在调用 gc_menu.add_item
之后发生分段错误并且 gc_menu.items->size
等于 72,而不是 new_mcl_items
.
定义中定义的 0
main.c
代码:
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()
returns。你不能用初始化器来做到这一点;全局或 static
对象的初始值设定项必须在编译或 link 时已知。标准 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();
// ...
}
我是 C 的新手,还不能自由浏览我的程序内存。无论如何,我正在创建一个静态内存数据类型(gc_menu
),它应该包含一个指向在执行时创建的结构(mcl_items
)的指针。
为简单起见,mcl_items
结构有一个虚拟方法 (push
),它将在 gc_menu_add_item
内部 运行 并分配给 gc_menu
静态 space。 push
将菜单项名称(字母)和方法保存到 mcl_item
虚拟对象。
mcl_items.h
代码:
[...]
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
代码:
[...]
#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
代码:
#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
代码:
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
在调用 gc_menu.add_item
之后发生分段错误并且 gc_menu.items->size
等于 72,而不是 new_mcl_items
.
main.c
代码:
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()
returns。你不能用初始化器来做到这一点;全局或 static
对象的初始值设定项必须在编译或 link 时已知。标准 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();
// ...
}