Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do strings make a copy of the data in it's constructor

In the following function (modified from another Stackoverflow post), I'm trying to use a unique_ptr so the memory allocated by the new gets freed later.

Is it safe to do std::wstring(res.get()) here? That is, will res be copied when the string constructor is called, so that if the memory allocated by new is freed, the returned value doesn't become garbage?

std::wstring narrow_to_wide_str(const std::string& input) {
    size_t size = input.size() + 1;
    size_t out_size;
    std::unique_ptr<wchar_t[]> res{ new wchar_t[size] };
    mbstowcs_s(&out_size, res.get(), size, input.c_str(), size - 1);
    return std::wstring(res.get());
}
like image 723
simonzack Avatar asked Jan 26 '23 15:01

simonzack


2 Answers

Is it safe to do std::wstring(res.get()) here?

Yes.

From std::basic_string::basic_string:

basic_string( const CharT* s, const Allocator& alloc = Allocator() ); (5)

5) Constructs the string with the contents initialized with a copy of the null-terminated character string pointed to by s. The length of the string is determined by the first null character. The behavior is undefined if [s, s + Traits::length(s)) is not a valid range (for example, if s is a null pointer). This constructor is not used for class template argument deduction if the Allocator type that would be deduced does not qualify as an allocator. (since C++17)

(Emphasize mine.)

like image 80
Scheff's Cat Avatar answered Feb 04 '23 04:02

Scheff's Cat


Yes, it's safe, but you don't need to use a pointer to a wchar_t[] here:

std::wstring narrow_to_wide_str(const std::string& input) {
    std::wstring res(input.size() + 1, L'\0');
    size_t out_size;
    mbstowcs_s(&out_size, res.data(), res.size(), input.c_str(), input.size());
    res.resize(out_size);
    return res;
}
like image 26
Ted Lyngmo Avatar answered Feb 04 '23 03:02

Ted Lyngmo