C语言通过传入函数指针修改跨函数传递的结构体数据失败问题
代码错误说明
核心问题是无意义的二级指针嵌套加多余取地址操作,触发未定义行为,代码根本没有访问到malloc申请的结构体内存,具体错误点:
func函数传参逻辑错误:func的形参user_data本身已经是void**类型(main中传入的是DATA_STRUCT*变量data的地址),调用传入的回调时又对user_data做了一次取地址&user_data,相当于传入三级指针后强制转成void**。回调中解引用拿到的是栈上func形参的地址,不是申请的结构体地址,修改操作完全写入了错误内存位置。- 二级指针滥用:需求仅为修改结构体实例的成员值,不需要修改外层指针本身的指向,完全没必要用
void**传参,用一级void*传递结构体地址即可,额外嵌套二级指针只会增加出错概率。 - 缺失必要头文件:原代码未包含
<stdio.h>和<stdlib.h>,printf、malloc没有正确声明,会触发编译警告甚至运行异常。
修正后代码
#include <stdio.h> #include <stdlib.h> typedef struct data_structs { int data1; int data2; } DATA_STRUCT; int inner_func(void* user_data) { DATA_STRUCT *inner_data = (DATA_STRUCT *)user_data; inner_data->data1 = 1; inner_data->data2 = 2; return 0; } void func(void *user_data, int (*passed_func)(void*)) { passed_func(user_data); } int main(void) { DATA_STRUCT *data = malloc(sizeof(DATA_STRUCT)); if (data == NULL) { return 1; } func(data, inner_func); printf("I expect 1 and 2 %d, %d\n", data->data1, data->data2); free(data); return 0; }
代码运行后会正确输出I expect 1 and 2 1, 2。
如果因接口规范要求必须保留void**传参形式,仅需把func中调用回调的语句改为passed_func(user_data),去掉多余的取地址和强转即可,但这种场景下二级指针属于冗余设计。
内容的提问来源于stack exchange,提问作者user3742046
相关产品推荐
相关产品推荐

