考虑以下功能:
unique_ptr<char> f(const wstring key, const unsigned int length)
{
assert(length <= key.length());
const wstring suffix = key.substr(length, key.length() - length);
const size_t outputSize = suffix.length() + 1; // +1 for null terminator
char * output = new char[outputSize];
size_t charsConverted = 0;
const wchar_t * outputWide = suffix.c_str();
wcstombs_s(&charsConverted, output, outputSize, outputWide, suffix.length());
return unique_ptr<char>(output);
}
这里的意图是接受一个wstring,从最后选择length
个字符,然后将它们作为一个C风格的字符串返回,该字符串包含在unique_ptr中(根据另一个库的要求 - 我当然没有选择)那种类型:))。
我的一位同事顺便说,他认为这会泄漏记忆,但他没有时间详细说明,我也看不到。任何人都可以发现它,如果是这样解释我应该怎么解决它?我可能有我的眼罩。
答案 0 :(得分:10)
它不一定是泄漏,但它是未定义的行为。您使用char
创建了new[]
数组,但unique_ptr<char>
将调用delete
而不是delete[]
来释放内存。请改用unique_ptr<char[]>
。
此外,您的转化可能并不总是按您希望的方式运作。您应该在wcstombs_s
中进行2次调用,在第一次传递nullptr
中作为第二个参数。这将返回输出字符串中所需的字符数。
wcstombs_s(&charsConverted, nullptr, 0, outputWide, suffix.length());
检查返回值,然后使用charsConverted
中存储的结果来分配输出缓冲区。
auto output = std::unique_ptr<char[]>(new char[charsConverted]);
// now use output.get() to get access to the raw pointer