基于libpcap的C语言网络嗅探器:IP转字符串乱码问题求助
问题分析与解决
你的get_ipaddress函数出现乱码的核心原因是malloc分配的内存未初始化:strcat要求目标字符串必须是以'\0'结尾的合法C字符串,但刚malloc出来的内存里是随机垃圾数据,strcat会从这些垃圾数据的末尾开始拼接,导致开头带上乱码。此外原代码里的临时缓冲区s长度设置也有问题,会存在缓冲区溢出风险。
方案1:修复原代码的核心问题
给malloc后的内存初始化,确保字符串起始为空,同时修正临时缓冲区的长度:
char* get_ipaddress(ipaddress *i) { char *ip = malloc(sizeof(char)*20); if (ip == NULL) { // 必须检查malloc是否成功,避免空指针操作 return NULL; } ip[0] = '\0'; // 关键:初始化字符串为空,让strcat能正确识别起始位置 for(unsigned int n = 0; n < i->p_int; n++) { char s[4]; // 单个IP段最多3位(如255),加上'\0'需要4字节空间 sprintf(s, "%d", i->p_data[n]); strcat(ip, s); if (n < i->p_int - 1) { strcat(ip, "."); } } return ip; }
方案2:更高效安全的实现(推荐)
用snprintf直接写入目标缓冲区,避免多次strcat的开销,同时实时监控剩余空间,彻底杜绝缓冲区溢出:
char* get_ipaddress(ipaddress *i) { // IPv4最长字符串为"255.255.255.255",共16字节(含'\0'),分配20字节足够冗余 char *ip = malloc(20 * sizeof(char)); if (ip == NULL) { return NULL; } ip[0] = '\0'; int offset = 0; for(unsigned int n = 0; n < i->p_int; n++) { // 写入当前IP段到缓冲区的offset位置,返回实际写入的字节数(不含'\0') int len = snprintf(ip + offset, 20 - offset, "%d", i->p_data[n]); if (len < 0 || len >= 20 - offset) { // 处理写入失败或空间不足的异常 free(ip); return NULL; } offset += len; if (n < i->p_int - 1) { if (offset >= 19) { // 剩余空间不足写入'.',直接释放内存返回 free(ip); return NULL; } ip[offset++] = '.'; ip[offset] = '\0'; // 保持字符串始终合法 } } return ip; }
额外注意事项
- 使用完返回的字符串后,必须调用
free(ip)释放内存,否则会造成内存泄漏。 - 确保
ipaddress结构体的p_int值为4(对应IPv4的4个字节),如果是IPv6场景,需要调整内存分配的大小(IPv6最长字符串为39字节)。
内容的提问来源于stack exchange,提问作者Chris Bao
相关产品推荐
相关产品推荐

