2

我目前正在学习 C++ Primer Fifth Edition。我已经阅读了其他几本 C++ 书籍,但它们不是很详细而且相当复杂。

这本书对我错过的一切帮助很大。我刚刚撞墙了。

其中一个练习要求我为一个函数编写一个声明,该函数返回一个包含十个字符串的数组的引用,而不使用尾随返回、decltype 或类型别名。

我知道它只说写一个声明,我已经这样做了,就像这样:

string (&returnArray()) [10];

我也想写一个函数定义,像这样:

string (&returnString(int i, string s)) [10]
{
    string s1[10];

    s1[i] = s;

    return s1;
}

在我的主函数中,我有一个 for 循环,它传递一个字符串文字并将该字符串存储在指向十个字符串数组的指针中。然后它应该将结果输出到屏幕上。

我遇到的问题是,当我取消引用指向数组的指针时,它会输出地址。如果我取消引用它两次,程序不会输出任何内容并停止响应。

这是我的主要功能,我已经更改了多次,但无法弄清楚为什么它不能正确输出。我可能全都搞错了...

int main()
{
    string (*s)[10];

    for(int i = 0; i != 10; ++i)
    {
            s = &returnString(i, "Hello");

            cout << s[i] << endl;
    }

    return 0;
}
4

3 回答 3

3

你的函数返回一个对局部变量的引用——在调用之后,它是一个悬空引用。你不能这样做。

您只能返回对函数调用结束后存在的存储的引用。

于 2013-10-09T13:11:40.023 回答
2

返回对临时本地对象的引用会调用未定义的行为。

一个简短的解决方法是static

string (&returnString(int i, string s)) [10]
{
    static string s1[10];
    ^^^^^^

    s1[i] = s;

    return s1;
}

int main()
{
    string(&s)[10] = returnString(0, "Hello");

    for (int i = 0; i != 10; ++i)
    {
        s[i] = "Hello";
        cout << s[i] << endl;
    }
}
于 2013-10-09T13:13:52.570 回答
0

返回对局部变量的指针/引用是不好的、未定义的行为。你可以跟随你的练习,不要忘记那个约束,你的练习告诉你做某事,但不一定告诉你以错误的方式去做,事实上它是一个很好的方法,它会导致你陷入陷阱,从而让你成为一个更好的程序员一旦你弄清楚了。

那么,考虑到不将地址返回给局部变量但仍然解决给定任务的约束,还剩下什么?您static已经提到了 M M. 的修复程序,或者您可能认为您正在创建一些有用的东西,例如一个函数rotate,例如,它接受一个string(&)[10]并返回旋转的自身;-)

看起来,iostream插入和提取运算符已经像那样工作了,返回对通过引用传递的参数的引用。

于 2013-10-09T20:58:43.550 回答