You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 22:36:33