其实已经有很多帖子提到通过GetAdaptersInfo方法获取网卡信息,但是使用过程中发现有内存泄漏的问题。仔细看了下 IP_ADAPTER_INFO这个结构体,这其实是一个链表结构,一开始用递归的方法遍历所有节点删除,发现内存泄漏还是没有解决,然后继续看了他的成员变量,部分成员变量也是链表结构。
typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO* Next;
DWORD ComboIndex;
char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
UINT AddressLength;
BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD Index;
UINT Type;
UINT DhcpEnabled;
PIP_ADDR_STRING CurrentIpAddress; //链表结构,有next指针
IP_ADDR_STRING IpAddressList;
IP_ADDR_STRING GatewayList;
IP_ADDR_STRING DhcpServer;
BOOL HaveWins;
IP_ADDR_STRING PrimaryWinsServer;
IP_ADDR_STRING SecondaryWinsServer;
time_t LeaseObtained;
time_t LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
如果需要遍历删除的话,那么还需要遍历这些成员变量,才能将所有内存都释放,考虑到申请内存的时候是一块连续的地址,因此用一个BYTE*的指针记住首地址,释放的时候直接调用delete []ptr;
//得到结构体大小,用于申请内存,及GetAdaptersInfo参数
unsigned long stSize = sizeof(IP_ADAPTER_INFO);
//PIP_ADAPTER_INFO结构体指针存储本机网卡信息
BYTE* pHeadIpAdapterInfo = new BYTE[stSize];
PIP_ADAPTER_INFO pIpAdapterInfo = (PIP_ADAPTER_INFO)pHeadIpAdapterInfo;
//调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量
int nRet = GetAdaptersInfo(pIpAdapterInfo,&stSize);
if (ERROR_BUFFER_OVERFLOW == nRet)
{
//如果函数返回的是ERROR_BUFFER_OVERFLOW
//则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小
//这也是说明为什么stSize既是一个输入量也是一个输出量
//释放原来的内存空间
if (pHeadIpAdapterInfo)
{
delete []pHeadIpAdapterInfo;
pHeadIpAdapterInfo = NULL;
}
//重新申请内存空间用来存储所有网卡信息
pHeadIpAdapterInfo = new BYTE[stSize];
pIpAdapterInfo = (PIP_ADAPTER_INFO)pHeadIpAdapterInfo;
//再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
nRet = GetAdaptersInfo(pIpAdapterInfo,&stSize);
}
//省略部分业务代码...
if (pHeadIpAdapterInfo)//内存释放
{
delete []pHeadIpAdapterInfo;
pHeadIpAdapterInfo = NULL;
}
这是我目前想到的方法,如果有更好的方法欢迎下方留言。
获取适配器信息参考的帖子:http://www.cnblogs.com/L-hq815/archive/2012/08/04/2622829.html