Строки делают копию данных в своем конструкторе - PullRequest
4 голосов
/ 04 ноября 2019

В следующей функции (измененной из другого поста Stackoverflow) я пытаюсь использовать unique_ptr, чтобы память, выделенная new, освобождалась позже.

Безопасно ли делать std::wstring(res.get()) здесь? То есть res будет скопировано при вызове строкового конструктора, так что если память, выделенная new, будет освобождена, возвращаемое значение не станет мусором?

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());
}

Ответы [ 2 ]

4 голосов
/ 04 ноября 2019

Да, это безопасно, но вам не нужно использовать указатель на wchar_t[] здесь:

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;
}
4 голосов
/ 04 ноября 2019

Безопасно ли здесь делать std::wstring(res.get())?

Да.

С std :: basic_string:: basic_string :

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

5) Создает строку с содержимым , инициализированным копией строки символов с нулевым символом в конце, на которую указывает s . Длина строки определяется первым нулевым символом. Поведение не определено, если [s, s + Traits :: length (s)) не является допустимым диапазоном (например, если s является нулевым указателем). Этот конструктор не используется для вывода аргумента шаблона класса, если тип распределителя, который должен быть выведен, не квалифицируется как распределитель. (начиная с C ++ 17)

(Подчеркните мое.)

...