C语言实现十六进制转二进制char数组 解决返回局部变量报错
代码错误说明
你的代码存在两个核心问题:
char output[] = ""是定义在函数栈上的局部数组,函数返回后该内存空间会被系统回收,此时返回这个数组的地址属于悬空指针,访问会触发未定义行为,这就是编译器提示"返回局部变量地址"的原因。- 初始化
output时仅分配了1字节空间(仅够存储空字符串的结束符\0),后续反复调用strcat追加内容会直接造成内存越界写入,破坏栈上的其他数据,哪怕不返回地址也会导致程序崩溃。
修正实现
最稳妥的实现方式是让调用方提前传入足够大小的输出缓冲区,不需要额外处理堆内存的分配释放,适合新手使用:
#include <string.h> #include <ctype.h> #include <stddef.h> /** * @param input 输入的十六进制字符串 * @param output 输出二进制字符串的缓冲区,长度至少为 输入字符串长度*4 +1(预留字符串结束符位置) * @return 转换后的二进制字符串长度,不包含结束符 */ size_t hex_to_bin(const char input[], char output[]) { // 十六进制字符对应4位二进制的映射表,替代冗长的switch判断 const char *hex_map[] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; size_t out_pos = 0; for (size_t i = 0; input[i] != '\0'; i++) { char c = input[i]; if (c >= '0' && c <= '9') { memcpy(output + out_pos, hex_map[c - '0'], 4); } else { // 统一转大写,兼容小写a-f输入 c = toupper(c); if (c >= 'A' && c <= 'F') { memcpy(output + out_pos, hex_map[10 + c - 'A'], 4); } else { // 遇到非法十六进制字符直接截断,可按需修改为返回错误码 break; } } out_pos += 4; } // 补全字符串结束符 output[out_pos] = '\0'; return out_pos; }
调用示例:
int main() { const char *hex_str = "a1F3"; // 输入共4个十六进制字符,缓冲区大小需要 4*4 +1 =17 字节 char bin_buf[17]; hex_to_bin(hex_str, bin_buf); // 执行后bin_buf内容为 "1010000111110011" return 0; }
这里用
memcpy代替strcat,一是避免strcat每次从头遍历字符串找结束位置的性能开销,二是直接按偏移量写入内容逻辑更清晰,不容易出现越界问题。
如果你一定要让函数直接返回生成的字符串,可以在函数内用malloc申请堆内存,注意调用方使用完必须手动调用free释放内存,否则会造成内存泄漏:
#include <stdlib.h> char *hex_to_bin_alloc(const char input[]) { size_t input_len = strlen(input); // 申请足够存储转换结果的堆空间 char *output = (char*)malloc(input_len * 4 + 1); if (output == NULL) return NULL; // 内存分配失败的异常处理 const char *hex_map[] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; size_t out_pos = 0; for (size_t i = 0; input[i] != '\0'; i++) { char c = input[i]; if (c >= '0' && c <= '9') { memcpy(output + out_pos, hex_map[c - '0'], 4); } else { c = toupper(c); if (c >= 'A' && c <= 'F') { memcpy(output + out_pos, hex_map[10 + c - 'A'], 4); } else { break; } } out_pos += 4; } output[out_pos] = '\0'; return output; } // 调用示例 int main() { char *bin_str = hex_to_bin_alloc("a1F3"); // 使用bin_str完成业务逻辑 free(bin_str); // 必须手动释放堆内存 return 0; }
内容的提问来源于stack exchange,提问作者Mobas
相关产品推荐
相关产品推荐

