C语言LVGL开发中子函数为嵌套结构体指针malloc分配内存失效问题
问题根因
- 核心是C语言的值传递规则:你给
CreateRadioButton传入的Settings->Some.Radio1是指针的副本,函数内部修改局部指针变量Radio的指向(赋值malloc返回的地址),完全不会影响外层的Settings->Some.Radio1的实际值。 - 子函数执行完成后,外层
Settings->Some.Radio1仍然是未初始化的野指针/空指针,后续访问该指针指向的内存就会触发非法访问,导致程序崩溃。 - 原可正常运行的代码是在上层函数
CreateDialog中直接给外层的Settings->Some.Radio1赋值malloc的有效地址,再把地址传入子函数操作结构体成员,因此不会出现指针丢失的问题。
修复方案
这里提供两种常用的可行实现:
方案1:子函数返回分配好的结构体指针
修改CreateRadioButton的返回值为已分配内存的AssetRADIOBUTTON指针,上层直接接收赋值即可:
// 修改函数返回值为指针类型 AssetRADIOBUTTON * CreateRadioButton(lv_obj_t * tab,unsigned char RadioCount) { AssetRADIOBUTTON * Radio = malloc(sizeof(*Radio) + RadioCount * sizeof(*Radio->btn)); // 建议增加malloc返回值判空,避免分配失败崩溃 if(Radio == NULL) { // 按需添加错误处理逻辑 return NULL; } Radio->Widgetcount = RadioCount; for(unsigned char i=0;i<RadioCount;i++) Radio->btn[i] = lv_checkbox_create(tab); Radio->index = 0; return Radio; } void CreateDialog(GUI_STRUCT_MODULES * Settings) { Settings->radioCOUNT = 4; // 直接接收子函数返回的指针赋值给外层变量 Settings->Some.Radio1 = CreateRadioButton(Settings->Some.tab,4); // 注意原错误代码里的Settings->ECG.tab属于笔误,对应结构体定义应该是Settings->Some.tab }
方案2:传入二级指针修改外层变量指向
如果不需要返回值,可以传入外层指针的地址,通过二级指针修改外层指针的指向:
// 参数改为二级指针 void CreateRadioButton(AssetRADIOBUTTON ** Radio,lv_obj_t * tab,unsigned char RadioCount) { *Radio = malloc(sizeof(**Radio) + RadioCount * sizeof((*Radio)->btn)); if(*Radio == NULL) { return; } (*Radio)->Widgetcount = RadioCount; for(unsigned char i=0;i<RadioCount;i++) (*Radio)->btn[i] = lv_checkbox_create(tab); (*Radio)->index = 0; } void CreateDialog(GUI_STRUCT_MODULES * Settings) { Settings->radioCOUNT = 4; // 传入外层指针的地址 CreateRadioButton(&Settings->Some.Radio1,Settings->Some.tab,4); }
额外注意事项
- 你提供的结构体定义中
GUI_STRUCT_MODULES的unsinged char radioCOUNT存在拼写错误,应为unsigned char radioCOUNT。 - 动态分配的内存使用完成后要记得调用
free释放,避免内存泄漏。 - LVGL的组件如果绑定了父对象,父对象删除时会自动释放子组件内存,不需要单独手动释放
btn数组成员。
内容的提问来源于stack exchange,提问作者vahid ajal
相关产品推荐
相关产品推荐

