首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取MAC地址的代码似乎会损坏内存,但只会在版本构建中损坏,而不是调试构建。

获取MAC地址的代码似乎会损坏内存,但只会在版本构建中损坏,而不是调试构建。
EN

Stack Overflow用户
提问于 2016-12-07 10:37:29
回答 1查看 258关注 0票数 0

下面的代码(在Embarcadero C++ Builder 2009中使用时,“Release”build )似乎正在破坏内存:

代码语言:javascript
复制
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也从未触发过。

感谢您的投入

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-07 18:59:30

您没有为您的MyGetAdaptersInfo变量声明调用约定,因此使用编译器的默认(通常是__cdecl)。但是GetAdaptersInfo()函数(以及大多数Win32 API)使用__stdcall调用约定,所以您需要在声明中包含它。

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

尝试更像这样的东西:

代码语言:javascript
复制
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;

    typedef DWORD (WINAPI *LPFN_GetAdaptersInfo)(PIP_ADAPTER_INFO, PULONG);

    DWORD GetIndex = (Index) ? *Index : 0;
    if (Index) *Index = 0;

    HMODULE khand = LoadLibrary(TEXT("Iphlpapi.dll"));
    if (khand)
    {
        LPFN_GetAdaptersInfo MyGetAdaptersInfo = (LPFN_GetAdaptersInfo) GetProcAddress(khand, "GetAdaptersInfo");
        if (MyGetAdaptersInfo)
        {
            DWORD MacBufLen = 0;
            if ((MyGetAdaptersInfo(NULL, &MacBufLen) == ERROR_BUFFER_OVERFLOW)
                && (MacBufLen > 0))
            {
                DynamicArray<BYTE> Buffer; // or std::vector<BYTE>
                Buffer.Length = MacBufLen;

                PIP_ADAPTER_INFO IPInfo = (PIP_ADAPTER_INFO) &Buffer[0];
                if (MyGetAdaptersInfo(IPInfo, &MacBufLen) == ERROR_SUCCESS)
                {
                    DWORD Cnt = 0;
                    do
                    {
                        if (GetIndex == Cnt)
                        {
                            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]) ;
                                }
                            }
                        }

                        ++Cnt;
                        IPInfo = IPInfo->Next;
                    }
                    while (IPInfo != NULL);

                    if (Index) *Index = Cnt;
                }
            }
        }

        FreeLibrary(khand);
    }

    return Address;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41015198

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档