c++ - 正确返回一个 unique_ptr

标签 c++ c++11

我正在写一个字符串类 MyString (是的,作为家庭作业)并且必须提供 toCString返回 unique_ptr<char[]> 的方法(而不是 Vector )。不幸的是,我在将指针返回给调用者时失败了:结果总是充满了错误的内容——似乎我在堆栈上创建了指针和/或字符数组。

unique_ptr<char[]> MyString::toCString() const {
     char *characters = new char[m_len];
     char *thisString = m_string.get();
     for (int i = 0; i < m_len; i++) {
         characters[i] = *(thisString + m_start + i);
     }
     const unique_ptr<char[], default_delete<char[]>> &cString = unique_ptr<new char[m_len]>(characters);
     return cString;
}

调试时,我总能得到预期的行为。问题只发生在来电者网站上。我的错误在哪里?

最佳答案

我看到已经有一个可接受的答案,但这并不能解决问题。客户端出现问题是因为您没有以空值终止 c 字符串。

我不知道 m_string 是什么类型,所以暂时假设它是一个 std::string。你可以自己翻译实际的方法:

std::unique_ptr<char[]> MyString::toCString() const 
{
    // get length (in chars) of string
    auto nof_chars = m_string.size();

    // allocate that many chars +1 for the null terminator.
    auto cString = std::unique_ptr<char[]>{new char[nof_chars + 1]};

    // efficiently copy the data - compiler will replace memcpy
    // with an ultra-fast sequence of instructions in release build
    memcpy(cString.get(), m_string.data(), nof_chars * sizeof(char));

    // don't forget to null terminate!!
    cString[nof_chars] = '\0';

    // now allow RVO to return our unique_ptr
    return cString;
}

根据 Christophe 的建议,这里再次使用该方法,以 std::copy_n 的形式编写。请注意,std::copy[_xxx] 函数套件都返回一个迭代器,该迭代器处理最后一次写入的后一个地址。我们可以使用它来保存重新计算空终止符的位置。标准库是不是很棒?

std::unique_ptr<char[]> MyString::toCString() const 
{
    // get length (in chars) of string
    auto nof_chars = m_string.size();

    // allocate that many chars +1 for the null terminator.
    auto cString = std::unique_ptr<char[]>{new char[nof_chars + 1]};

    // efficiently copy the data - and don't forget to null terminate
    *std::copy_n(m_string.data(), nof_chars, cString.get()) = '\0';

    // now allow RVO to return our unique_ptr
    return cString;
}

关于c++ - 正确返回一个 unique_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36374717/

相关文章:

c++ - 用作模板类型时,size_t 类型和 int 类型的用法有何区别?

c++ - 使用带接口(interface)的 CRTP

c++ - 为什么删除复制构造函数时默认初始化会失败?

c++ - FD_CLOSE 事件处理器 C++

C++、linux、无需root的关机命令

c++ - 根据 C++11 标准中的 §12.1/4,代码不应编译

c++ - 带有模板参数的 make_tuple 不编译

c++ - 重新排序可变参数

c++ - boost IPC Message_Queue try_receive 抛出 interprocess_exception::library_error

c++ - 为什么函数声明中允许使用 const?