问题 将char数组作为std:string返回


以下是否安全,没有显式强制转换或调用std :: string构造函数?如果不安全,为什么不呢?

std:string myfunc()
{
    char buf[128] = "";
    // put something into buf or not base on logic.

   return buf;
}

2163
2018-03-16 16:37


起源

实际上问题的标题是不正确的。您将char数组作为std :: string返回。 - Benoit
编辑了题目标题。 - Sylvain Defresne


答案:


是。那很好。调用者将获得本地缓冲区的副本,因为 std::string 将从本地缓冲区中复制出来!

编辑:我假设了 buf 是以null结尾的字符串!


9
2018-03-16 16:39



除非buf绝对无效,否则不安全! - T33C
@ T33C:正确。我添加了这个基本假设! - Nawaz
假设事情是不好的编程实践。相反,应该确保回报是安全的。如果后来修改了buf,则问题中的代码无法确保这一点。 - T33C


是的,没关系,请记住在C ++中,将会发生一个隐式构造函数来创建返回对象,并且可以使用字符数组构造一个字符串。在C ++中,如果不想创建副本,则必须通过引用显式返回。


4
2018-03-16 16:42



除非buf绝对无效,否则不安全! - T33C
它是安全的,正如下面@karlphillip所描述的那样,因为语句char buf [128] =“”;是一个初始化,它将buf设置为指向空终止的空字符串,它不是在数组中设置单个字符。 - titania424


实际上,它是安全的。但那只是因为你正在初始化 char array 就是这样,这是 非常重要。请考虑以下代码:

#include <string.h>
#include <iostream>
#include <string>

std::string alloc_string(bool fill)
{
    char buf[128] = ""; // Proper declaration/initialization of the array. 

    if (fill)
    {
        strcpy(buf, "qwerty");
    }

    return buf;
}

int main()
{
    std::string empty_str = alloc_string(false);
    std::cout << "empty_str size is: " << empty_str.size() << std::endl;

    std::string str = alloc_string(true);
    std::cout << "str size is: " << str.size() << std::endl;
    std::cout << "str: " << str << std::endl;
}

输出:

empty_str size is: 0
str size is: 6
str: qwerty

3
2018-03-16 17:02



如果你忘记初始化数组,你肯定会破坏代码,因为那块内存可能有垃圾。试试看,你可能会注意到这一点 empty_str 即使你没有复制任何东西,它也不再是空的。 - karlphillip


安全(对于空终止缓冲区)但不容易阅读,考虑将最后一行更改为

return std::string(buf);

编辑:请参阅karlphillip的安全性。


0
2018-03-16 17:51