第一次调用GetAdaptersAddresses返回ERROR_BUFFER_OVERFLOW是正常行为,需先传NULL获取所需缓冲区大小,再分配内存重试,并用FreeMibTable释放。

直接用 GetAdaptersAddresses 就行,但必须传对参数、处理好内存和错误码,否则返回 ERROR_BUFFER_OVERFLOW 或空结果是常态。
为什么第一次调用总返回 ERROR_BUFFER_OVERFLOW
这是正常行为,不是出错。Windows 要求你先调用一次获取所需缓冲区大小,再分配对应内存重试。
- 第一次传
NULL作pAdapterAddresses,SizePointer指向一个ULONG变量,函数会把需要的字节数写进去 - 立刻检查返回值:如果是
ERROR_BUFFER_OVERFLOW,说明要重来;如果是NO_ERROR,说明缓冲区够大(极少见) - 用拿到的大小
malloc一块内存,第二次传进去,别忘了把SizePointer也更新为该大小 - 别漏掉
FreeMibTable—— 这个函数返回的内存必须用它释放,不能用free或delete
GetAdaptersAddresses 的关键参数怎么设
参数看似多,真正要小心的就三个:地址族、标志、缓冲区。
-
Family填AF_UNSPEC才能拿到 IPv4 + IPv6 信息;填AF_INET会过滤掉纯 IPv6 适配器 -
Flags推荐用GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,否则FirstPrefix和网关字段为空 -
Reserved必须传NULL,传别的值会导致返回ERROR_INVALID_PARAMETER - 缓冲区指针和大小变量必须是栈上变量或明确初始化过的内存,别传野指针
遍历结果时最容易崩的几个点
返回的 PIP_ADAPTER_ADDRESSES 是链表,但 Windows 不保证节点数量稳定——热插拔网卡、DHCP 更新都可能让结构体内容临时不一致。
立即学习“C++免费学习笔记(深入)”;
- 每次访问
pAdapter->FirstUnicastAddress前,先判空;同理检查FirstGatewayAddress、FirstDnsServerAddress - 获取 IP 地址要用
getnameinfo或inet_ntop,别直接读sockaddr_in->sin_addr字段——IPv6 下结构体不同,硬读会越界 -
AdapterName是内核名(如{846EE342-7039-11DE-9D20-806E6F6E6963}),要显示给用户得查AdapterDescription字段 - 某些虚拟网卡(如 Docker、WSL2)可能没有 IPv4 地址,只有 IPv6 链路本地地址,
AddressLength == 16且sin6_scope_id != 0就是这种
实际跑起来最常卡在没处理好两次调用的内存生命周期,或者忽略 GetAdaptersAddresses 在低权限进程里拿不到部分适配器(比如 Hyper-V 虚拟交换机)。真要全量采集,得确保进程至少是普通用户权限,别在受限服务上下文中硬刚。


















