Я следую 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);
Вы бы не заменили эти виды использования 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[]
.)