C语言如何访问结构体函数指针成员调用后的返回值
问题产生原因
你读不到预期返回值的核心错误是混淆了函数指针本身和函数调用的返回值:
pr_t结构体里的TrimS是函数指针类型的成员,执行SP2->TrimS = ChopS赋值后,这个成员存储的是ChopS函数在内存中的入口地址,本身不会存储函数的执行结果。你直接读取SP2->TrimS的值,拿到的自然是函数地址,也就是你看到的类似垃圾值的内容,和0/-1的状态返回值没有任何关系。
除此之外你的代码还有两个会触发未定义行为的隐藏bug,会进一步导致运行结果不符合预期:
- 你通过
malloc给tS2分配了S_t结构体的内存,但没有初始化结构体内部的s_ptr指针和ns成员:s_ptr是野指针,ns是随机值,进入ChopS后访问TS->s_ptr[i]属于非法内存访问,会直接导致程序崩溃或者结果随机。 ChopS本身的判断逻辑错误:你把下标大于等于size的元素置0后,统计整个数组里0元素的总数c,再判断c == size——只有数组前size个元素本身全为0时这个条件才成立,正常场景下永远会返回failure,和截断数组的预期逻辑不符。
正确获取返回值的方式
C语言中函数的返回值只会在函数调用执行时生成,你需要定义一个整型变量,在调用函数的位置接住返回结果,而不是直接读取函数指针成员。
正确的初始化、调用、取值代码示例:
// 补全之前缺失的S_t成员初始化 tS2->ns = 16; // 替换为你实际需要的数组长度 tS2->s_ptr = malloc(sizeof(float) * tS2->ns); // 给浮点数组分配对应内存 // 如果需要可以给数组赋初始值,比如前8位设为非0值方便测试 for (int i = 0; i < 8; i++) { tS2->s_ptr[i] = 1.0f; } // 调用函数指针指向的方法,用变量接收返回值 int exec_status = SP2->TrimS(tS2, 8); // exec_status就是ChopS执行后的状态值,为success(0)或failure(-1)
可选逻辑优化
如果你的需求是"将数组size下标之后的元素全部置0,操作合法就返回成功",可以把ChopS改成更简洁健壮的实现,避免无意义的二次遍历:
int ChopS(S_t *TS, int size) { // 先校验入参合法性,拦截空指针、长度非法的异常场景 if (TS == NULL || TS->s_ptr == NULL || size < 0 || size > TS->ns) { return failure; } // 直接从size位置开始遍历置0即可,不需要遍历前size个元素 for (int i = size; i < TS->ns; i++) { TS->s_ptr[i] = 0.0f; } return success; }
内容的提问来源于stack exchange,提问作者skrowten_hermit
相关产品推荐
相关产品推荐

