VC2005运行下面一段代码,是从MSDN的例子简化而来的,目的是打印当前机器所有MAC地址。工程是MFC控制台程序。问题:
1. 我发现如果用F5调试的话, 会中断到osfinfo.c的第467行。弹筐提示说: 
Windows has triggered a breakpoint in xxx.exe
This may be due to a corruption of the heap, and indicates a bug in xxx.exe or any of the DLLs it has loaded.
The output window may have more diagnotic information.
2. 断点跟踪发现是在最后面的HeapFree出了问题。这到底是为什么呢?还请大虾解救!#include "stdafx.h"
#include <Winsock2.h>
#include <Iphlpapi.h>
#pragma comment(lib,"Iphlpapi")
#pragma warning( disable : 4996 )
#define MACSESION 6
int main(void)
{
    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    ULONG family = AF_INET;
    ULONG flags  = GAA_FLAG_INCLUDE_PREFIX;
    ULONG outBufLen = sizeof( IP_ADAPTER_ADDRESSES  );    // Make an initial call to GetAdaptersAddresses to get the 
    // size needed into the outBufLen variable
    if ( GetAdaptersAddresses( family, flags, NULL, pAddresses, &outBufLen ) == ERROR_BUFFER_OVERFLOW )
    {
        pAddresses = static_cast<PIP_ADAPTER_ADDRESSES>( HeapAlloc( GetProcessHeap(), 0, outBufLen ) );
    }    _ASSERT( pAddresses );
    // Make a second call to GetAdapters Addresses to get the
    // actual data we want
    DWORD dwRetVal = GetAdaptersAddresses( family, flags, NULL, pAddresses, &outBufLen );    while( pAddresses )
    {
        BYTE* pa = pAddresses->PhysicalAddress;
        if ( ! pa[ 0 ] )
        {
            break;
        }
        char bAddr[ MACSESION ];
        memset( bAddr, 0, MACSESION );
        size_t nAddressSize = pAddresses->PhysicalAddressLength;
        memcpy( bAddr, pa, ( nAddressSize < MACSESION ? nAddressSize : MACSESION ) );
        pAddresses = pAddresses->Next ? pAddresses->Next : NULL;
        printf(" %c %c %c %c %c %c \n", bAddr[0],bAddr[1],bAddr[2],bAddr[3],bAddr[4],bAddr[5]);
    }
    HeapFree( GetProcessHeap(), 0, pAddresses );
    return 0;
}

解决方案 »

  1.   

    vs2010编译没什么问题。使用HeapAlloc、HeapFree和使用new、delete结果一样。代码稍做了修改:#include <Winsock2.h>
    #include <Windows.h>
    #include <Iphlpapi.h>
    #include <assert.h>
    #include <stdio.h>
    #include <locale.h>
    #pragma comment(lib,"Iphlpapi")
    //#pragma warning( disable : 4996 )
    #define MACSESION 6
    int main(void)
    {
    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    ULONG family = AF_INET;
    ULONG flags  = GAA_FLAG_INCLUDE_PREFIX;
    ULONG outBufLen = sizeof( IP_ADAPTER_ADDRESSES  ); setlocale(LC_ALL,"chs"); // Make an initial call to GetAdaptersAddresses to get the 
    // size needed into the outBufLen variable
    if ( GetAdaptersAddresses( family, flags, NULL, pAddresses, &outBufLen ) == ERROR_BUFFER_OVERFLOW )
    {
    //pAddresses = static_cast<PIP_ADAPTER_ADDRESSES>( HeapAlloc( GetProcessHeap(), 0, outBufLen ) );
    pAddresses = (PIP_ADAPTER_ADDRESSES)new char[outBufLen];
    } assert( pAddresses );
    // Make a second call to GetAdapters Addresses to get the
    // actual data we want
    DWORD dwRetVal = GetAdaptersAddresses( family, flags, NULL, pAddresses, &outBufLen );
    unsigned char bAddr[ MACSESION ];
    BYTE* pa;
    size_t nAddressSize;
    while( pAddresses )
    {
    pa = pAddresses->PhysicalAddress;
    if ( ! pa/*[ 0 ]*/ )
    {
    break;
    }

    memset( bAddr, 0, MACSESION );
    nAddressSize = pAddresses->PhysicalAddressLength;

    memcpy( bAddr, pa, ( nAddressSize < MACSESION ? nAddressSize : MACSESION ) );

    wprintf_s(pAddresses->Description); printf("\n%02X %02X %02X %02X %02X %02X\n", bAddr[0],bAddr[1],bAddr[2],bAddr[3],bAddr[4],bAddr[5]); pAddresses = pAddresses->Next;
    } //HeapFree( GetProcessHeap(), 0, pAddresses );
    delete pAddresses; return 0;
    }
      

  2.   

    pAddresses = pAddresses->Next ? pAddresses->Next : NULL;
    这行代码会改变pAddresses的值,后面再释放时pAddresses已经不是最初分配的地址,所以出错。另外定义一个指针变量来使用即可。