如何在示例中用new替换malloc

时间:2013-03-28 19:19:28

标签: c++ malloc msdn

我正在关注管理IP地址的C ++ msdn参考。示例中的内存分配使用malloc而不是new。我的理解是malloc永远不应该在C ++中使用。我将如何将这些malloc转换为新的?

链接:MSDN REFERENCE

有问题的代码:

MIB_IPADDRTABLE  *pIPAddrTable;
DWORD            dwSize = 0;
DWORD            dwRetVal;

pIPAddrTable = (MIB_IPADDRTABLE*) malloc( sizeof(MIB_IPADDRTABLE) );

if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
{
    free( pIPAddrTable );
    pIPAddrTable = (MIB_IPADDRTABLE *) malloc ( dwSize );
}

if ( (dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 )) != NO_ERROR )
{ 
    printf("GetIpAddrTable call failed with %d\n", dwRetVal);
}

printf("IP Address:         %ld\n", pIPAddrTable->table[0].dwAddr);
printf("IP Mask:            %ld\n", pIPAddrTable->table[0].dwMask);
printf("IF Index:           %ld\n", pIPAddrTable->table[0].dwIndex);
printf("Broadcast Addr:     %ld\n", pIPAddrTable->table[0].dwBCastAddr);
printf("Re-assembly size:   %ld\n", pIPAddrTable->table[0].dwReasmSize);

if (pIPAddrTable)
    free(pIPAddrTable);

2 个答案:

答案 0 :(得分:3)

您不会将malloc的这些用法替换为 new-expression ,因为它们不会像new那样初始化对象。相反,它们将指向已分配内存的指针传递给GetIpAddrTable,这似乎代替了初始化。

但是,有malloc的C ++版本只进行内存分配:operator new。我会将这些线与他们的替换配对:

pIPAddrTable = (MIB_IPADDRTABLE*) malloc( sizeof(MIB_IPADDRTABLE) );
pIPAddrTable = (MIB_IPADDRTABLE*) ::operator new( sizeof(MIB_IPADDRTABLE) );

pIPAddrTable = (MIB_IPADDRTABLE *) malloc ( dwSize );
pIPAddrTable = (MIB_IPADDRTABLE*) ::operator new( dwSize );

free的用法也需要用释放函数operator delete替换:

free( pIPAddrTable );
::operator delete(pIPAddrTable);

答案 1 :(得分:3)

如果您想使用现代C ++重新编写原始C风格的代码,您应该使用 std::vector 而不是new[](以及malloc)。

std::vector非常方便,例如由于它的析构函数(在抛出异常的情况下)它会自动释放它的内存,它可以调整大小等等。

这是上述代码的示例,它使用std::vector代替mallocnew[](有关详细信息,请参阅代码中的注释):

#include <windows.h>
#include <Iphlpapi.h>
#include <stdio.h>
#include <vector>       // for std::vector

#pragma comment(lib, "iphlpapi.lib")

int main()
{
    // Use std::vector to dynamically allocate memory.
    std::vector<BYTE> buffer(sizeof(MIB_IPADDRTABLE));
    MIB_IPADDRTABLE * pIPAddrTable = reinterpret_cast<MIB_IPADDRTABLE*>(&buffer[0]);

    DWORD dwSize = 0;      
    if ( GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER )
    {
        // Resize buffer to proper size
        buffer.resize(dwSize);        

        // Buffer memory can be re-based after allocation, so update base pointer
        pIPAddrTable = reinterpret_cast<MIB_IPADDRTABLE*>(&buffer[0]);
    }

    DWORD dwRetVal;   
    if ( (dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 )) != NO_ERROR )
    { 
        printf("GetIpAddrTable call failed with %d\n", dwRetVal);
    }

    printf("IP Address:         %ld\n", pIPAddrTable->table[0].dwAddr);
    printf("IP Mask:            %ld\n", pIPAddrTable->table[0].dwMask);
    printf("IF Index:           %ld\n", pIPAddrTable->table[0].dwIndex);
    printf("Broadcast Addr:     %ld\n", pIPAddrTable->table[0].dwBCastAddr);
    printf("Re-assembly size:   %ld\n", pIPAddrTable->table[0].dwReasmSize);

    //
    // No need to cleanup memory:
    // std::vector destructor will do that for us automatically :)
    //    
}

(请注意,printf()可以替换为std::cout,但它不如使用std::vector代替mallocnew[]那么重要。)