我正在关注管理IP地址的C ++ msdn参考。示例中的内存分配使用malloc而不是new。我的理解是malloc永远不应该在C ++中使用。我将如何将这些malloc转换为新的?
有问题的代码:
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);
答案 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
代替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[]
那么重要。)