我有以下功能:
std::wstring GetNetStatus()
{
NETSETUP_JOIN_STATUS bufType;
::ZeroMemory(&bufType, sizeof(NETSETUP_JOIN_STATUS));
LPWSTR buf;
CHECK_OS_ERROR(::NetGetJoinInformation(nullptr, &buf, &bufType) == NERR_Success);
std::wstring group(buf);
::NetApiBufferFree(buf);
return group;
}
我需要返回一个
LPWSTR
值,但是根据我使用的API,我需要在离开函数范围之前释放该指针。向STL字符串分配
LPWSTR
值并返回它是否正确,或者还有其他技巧吗? 最佳答案
您显示的内容在技术上是正确的。
但是,请注意,当std::wstring
从buf
复制字符数据时,它有可能引发异常,因此您应该准备处理该异常以避免任何可能的内存泄漏。
您可以使用__try/__finally
:
std::wstring GetNetStatus()
{
std::wstring result;
NETSETUP_JOIN_STATUS bufType;
::ZeroMemory(&bufType, sizeof(NETSETUP_JOIN_STATUS));
LPWSTR buf;
CHECK_OS_ERROR(::NetGetJoinInformation(nullptr, &buf, &bufType) == NERR_Success);
try {
result = buf;
}
__finally {
::NetApiBufferFree(buf);
}
return result;
}
或者,您可以编写遵循RAII语义的自定义
class
/ struct
:template <typename T>
class NetApiBuffer
{
private:
T* m_buf;
NetApiBuffer(const NetApiBuffer &) {}
NetApiBuffer& operator=(const NetApiBuffer &) { return *this; }
public:
NetApiBuffer(T *buf = 0) : m_buf(buf) {}
~NetApiBuffer() {
::NetApiBufferFree(m_buf);
}
operator T*() { return m_buf; }
T** operator&() { return &m_buf; }
};
std::wstring GetNetStatus()
{
NETSETUP_JOIN_STATUS bufType;
::ZeroMemory(&bufType, sizeof(NETSETUP_JOIN_STATUS));
NetApiBuffer<WCHAR> buf;
CHECK_OS_ERROR(::NetGetJoinInformation(nullptr, &buf, &bufType) == NERR_Success);
return std::wstring(buf);
}
或者,如果您使用的是C++ 11或更高版本,则可以将
std::unique_ptr
与自定义删除器一起使用:std::wstring GetNetStatus()
{
NETSETUP_JOIN_STATUS bufType;
::ZeroMemory(&bufType, sizeof(NETSETUP_JOIN_STATUS));
LPWSTR buf;
CHECK_OS_ERROR(::NetGetJoinInformation(nullptr, &buf, &bufType) == NERR_Success);
std::unique_ptr<WCHAR, decltype(&::NetApiBufferFree)> deleter(buf, &::NetApiBufferFree);
return std::wstring(buf);
}