获取MAC地址的代码似乎破坏了内存,但仅限于Release版本,而不是Debug build

时间:2016-12-07 10:37:30

标签: c++ winapi c++builder

以下代码,当在Embarcadero C ++ Builder 2009中使用时,'Release'版本似乎破坏了内存:

String MyCode::MacAddress(bool Dashes, DWORD *Index)
{
// Dashes to build the string with dashes or not: 00-14-22-01-23-45 vs. 001422012345

// Index is Input and Output.
// If NULL or Index==0 the first Mac address is requested.
// If > 0 that mac address is requested (0 based index)
// The return value, if !NULL, is always the count of available mac addresses

String Address ;

DWORD (*MyGetAdaptersInfo)(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) = NULL ;
HMODULE khand = NULL ;
DWORD GetIndex = (Index)?(*Index):(0) ;
if (Index) *Index = 0 ;

if (!khand)
    {
    khand = LoadLibrary(TEXT("Iphlpapi.dll")) ;

    if (khand)
        {
        MyGetAdaptersInfo = (DWORD (*)(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)) GetProcAddress(khand, "GetAdaptersInfo") ;
        }
    }

if (MyGetAdaptersInfo)
    {
    DWORD MacBufLen = 0 ;
    IP_ADAPTER_INFO IPInfo ;
    MyGetAdaptersInfo(&IPInfo, &MacBufLen) ;
    if (MacBufLen)
        {
        BYTE *Buffer = new BYTE[MacBufLen] ;
        if (Buffer)
            {
            IP_ADAPTER_INFO *IPInfo = (IP_ADAPTER_INFO*)Buffer ;
            if (MyGetAdaptersInfo(IPInfo, &MacBufLen) == ERROR_SUCCESS)
                {
                DWORD Cnt = (MacBufLen / sizeof(IP_ADAPTER_INFO)) ;
                if (Index) *Index = Cnt ;
                if (GetIndex < Cnt)
                    {
                    IPInfo = (IP_ADAPTER_INFO*) &Buffer[(GetIndex * sizeof(IP_ADAPTER_INFO))] ;
                    for (DWORD x = 0 ; x < IPInfo->AddressLength ; x++)
                        {
                        if (!Dashes || x == (IPInfo->AddressLength - 1))
                            {
                            Address += String().sprintf(L"%.2X", (int)IPInfo->Address[x]) ;
                            }
                        else
                            {
                            Address += String().sprintf(L"%.2X-", (int)IPInfo->Address[x]) ;
                            }
                        }
                    }
                }
            }
        delete[] Buffer ;
        }
    }

FreeLibrary(khand) ;

return Address ;
}

你能看到我目前看不到的东西吗?

我一直在调试版本中使用此代码一段时间没有问题。所以我从不怀疑它的正确功能。但是现在我使用Embarcadero c ++ Builder 2009构建了一个发布版本,它似乎破坏了之后调用的其他功能的内存,最终导致异常错误。

当我从代码中移除MacAddress()调用时,所有调用都会再次像魅力一样。

在调试模式下,CodeGuard从未触发过。

您的意见赞赏

1 个答案:

答案 0 :(得分:2)

您没有声明f = open("file.csv") parsed_lines = [] for line in f: vals = line.split(",") parsed_lines.append(map(str.strip, vals)) for idx, vals in enumerate(parsed_lines): for jdx in range(idx+1, len(parsed_lines)): if (vals[0]==parsed_lines[jdx][0]) and \ (vals[1]==parsed_lines[jdx][1]) and \ (vals[2]==parsed_lines[jdx][2]) and \ (vals[3]==parsed_lines[jdx][3]): print "line #%s looks similar to line #%s" % (idx+1,jdx+1) 变量的调用约定,因此使用编译器的默认值(通常为MyGetAdaptersInfo)。但是__cdecl函数(以及大多数Win32 API)使用GetAdaptersInfo()调用约定,因此您需要在声明中包含它。

此外,您也不应该依赖__stdcall。它的大小可以从一个操作系统版本更改为另一个操作系统版本,并且无法知道给定版本实际使用的大小。 sizeof(IP_ADAPTER_INFO)实现为链接列表(即使它被分配为单个连续的内存缓冲区),您需要使用IP_ADAPTER_INFO字段正确地遍历列表。

尝试更像这样的事情:

IP_ADAPTER_INFO::Next