函数内为指针形参赋值地址后,外部temp_reg仍为NULL的原因?
问题分析与解决方法
核心原因
C语言采用值传递机制,你传入函数的temp_reg是指针变量的副本(即形参reg)。在函数内部对reg赋值,只是修改了这个副本的指向,完全不会影响外部的temp_reg变量——这就是为什么函数退出后temp_reg还是NULL。
解决方案
有两种常用的修正方式:
方式一:使用二级指针(指针的指针)传递
修改函数定义,用二级指针接收外部指针的地址,这样就能通过解引用修改外部指针的指向:
uint8_t cargo_command_get_register_handle(uint16_t address, soft_register_t** reg) { if(address > MAX_REGISTER_ADDRESS) return 1; // 获取目标寄存器的地址 soft_register_t* target_addr = ®ister_base[register_hash_table[address].base_index].reg_table[register_hash_table[address].sub_index]; // 直接修改外部指针的指向 *reg = target_addr; return 0; }
调用时传入外部指针的地址:
soft_register_t* temp_reg = NULL; cargo_command_get_register_handle(reg_address, &temp_reg);
方式二:让函数直接返回目标指针
调整函数返回值类型为指针,把目标地址作为返回值返回,同时用返回NULL表示失败:
soft_register_t* cargo_command_get_register_handle(uint16_t address) { if(address > MAX_REGISTER_ADDRESS) return NULL; return ®ister_base[register_hash_table[address].base_index].reg_table[register_hash_table[address].sub_index]; }
调用时直接接收返回值:
soft_register_t* temp_reg = cargo_command_get_register_handle(reg_address);
额外说明
原函数中的if(®ister_base[...] != NULL)判断没有实际意义——数组元素的内存地址永远不会是NULL,只要address合法,这个地址必然有效。如果需要校验哈希表的索引合法性,可以针对register_hash_table[address].base_index和sub_index做范围检查。
内容的提问来源于stack exchange,提问作者ESD
相关产品推荐
相关产品推荐

