Как заменить malloc на новый в примере

Я следую C++ msdn ссылку для управления IP-адресами. Распределение памяти в примере использует malloc вместо new. Насколько я понимаю, malloc никогда не должен использоваться в C++. Как мне перевести эти malloc в новые?

Ссылка: MSDN ССЫЛКА

Код в вопросе:

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 ответа

Решение

Вы бы не заменили эти виды использования malloc с новым выражением, потому что они не инициализируют объект как new было бы. Вместо этого они передают указатель на выделенную память GetIpAddrTable, который, кажется, вместо этого выполняет инициализацию.

Тем не менее, существует версия C++ malloc который только выделяет память: 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);

Если вы хотите переписать этот оригинальный код в стиле C с использованием современного C++, вам следует использовать std::vector вместо new[] (а также malloc).

std::vector очень удобно, например, он автоматически освобождает память благодаря деструктору (также в случае возникновения исключений), его размер можно изменять и т. д.

Это пример приведенного выше кода, который использует std::vector вместо malloc а также new[] (см. комментарии в коде для получения дополнительной информации):

#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 вместо malloc или же new[].)

Другие вопросы по тегам