c - 在 const 表达式中声明指向结构的指针
问题描述
我是 C 的新手,还不能自由地浏览我的程序内存。无论如何,我正在创建一个静态内存数据类型 ( gc_menu
),它应该包含一个指向在执行时创建的结构 ( mcl_items
) 的指针。
为简单起见,mcl_items
结构有一个虚拟方法 ( push
),它将在其中运行gc_menu_add_item
并分配给gc_menu
静态空间。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,而不是定义中定义的 0 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
那么我做错了什么?为什么会有如此奇怪的数据写入 my 的实例gc_menu.items
?
解决方案
您已经初始化gc_menu.items
为new_mcl_items
,即指向函数的指针new_mcl_items
(它应该给您一个警告,因为它是 typemcl_items *(*)(void)
而不是mcl_items *
)。
看起来您想要的是实际调用该函数new_mcl_items()
并设置为返回gc_menu.items
的值new_mcl_items()
。你不能用初始化器来做到这一点;全局或对象的初始化器static
必须在编译或链接时已知。标准 C 没有“构造函数”。
因此,您必须const
从 的声明和定义中删除 ,并向(或由 调用的某些函数等)gc_menu
添加代码以在运行时进行初始化。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();
// ...
}
推荐阅读
- javascript - 如何使用 Jquery 将搜索值附加到 url?
- mongodb - MongoDB Mongoose Group by 和 count
- unity3d - Unity Editor Scripting:类似于 BoxCollider 的场景控件
- c# - 如何在没有 Windows 运行时组件的 C# UWP 应用程序中导入 C++ Legacy DLL
- python - 是否有 python 库可以根据投资组合权重和股票价格计算时间加权回报?
- java - 删除对“Log4j 2”的直接依赖
- amazon-web-services - 有条件地更新集合属性并跟踪其中的元素数量 DynamoDB Node.js
- jquery - 如何选择数据表 1.9 中当前页面中显示的行?
- windows-10 - 更新到 Windows 10 1903 后指纹传感器不工作。(Dell G3 3579)
- java - google cloud vision api OCR 边界框