You need to enable JavaScript to run this app. C语言遍历ai_next链表时空指针检查失效触发段错误
优惠活动
大模型
产品
解决方案
定价
更多

C语言遍历ai_next链表时空指针检查失效触发段错误

段错误根因排查与修复方案

核心错误点

  • 字段赋值混淆导致配置非法
    你在初始化hints结构体时,错误地将本该赋值给ai_flags字段的AI_PASSIVE常量,重复赋值给了ai_family字段:
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_family = AI_PASSIVE; // 致命错误:覆盖了合法的地址族配置
    
    AI_PASSIVE是地址配置的标志位,不属于地址族字段的合法取值。这次赋值会把之前配置的AF_UNSPEC覆盖成AI_PASSIVE对应的数值,直接给getaddrinfo传入非法参数,导致函数调用直接失败。
  • 缺少getaddrinfo返回值校验
    你直接调用完getaddrinfo就使用输出指针res,完全没有检查函数执行结果。一旦getaddrinfo调用失败,它不会给res分配合法的链表内存,也不会主动将res设置为NULL,此时res是栈上的未初始化野指针,值为随机垃圾数。
    这种情况下你写的addr != NULL判断完全失效——因为野指针本身不等于NULL,循环会直接进入,解引用指向非法内存的指针时就会触发段错误。

正确的修复代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>

#define MYPORT "6161"

int main() {
    struct addrinfo hints, *res = NULL; // 主动初始化res为NULL,避免野值问题
    int gai_ret;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; // 把AI_PASSIVE放到正确的ai_flags字段

    // 必须检查getaddrinfo的返回值
    gai_ret = getaddrinfo(NULL, MYPORT, &hints, &res);
    if (gai_ret != 0) {
        fprintf(stderr, "getaddrinfo调用失败: %s\n", gai_strerror(gai_ret));
        return 1;
    }

    struct addrinfo *addr;
    for (addr = res; addr != NULL; addr = addr->ai_next) {
        printf("Here's one addr!\n"); // 补充换行符避免输出缓冲不显示
    }

    // 遍历完成后必须释放getaddrinfo分配的链表内存,避免泄漏
    freeaddrinfo(res);
    return 0;
}

补充说明

你之前用远程地址的代码运行正常,本质是当时没有出现字段赋值错位的问题,getaddrinfo能正常返回合法的地址链表。本次的段错误和配置本机/远程地址没有关系,完全是赋值笔误加缺少错误校验导致的。

内容的提问来源于stack exchange,提问作者Dylan Landry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.11 08:45:04