lenlendenuan 2024-07-10 20:45 采纳率: 0%
浏览 4

C++11左右值问题

关于C++11的左值,右值,下面两段代码,都是返回函数内部的局部变量,为啥一个奔溃一个正常呢?

这段代码编译通过,运行报SIGSEGV。


string& add(string a, string b)
{
    string c = a + b;
    return c;
}

string &c = add("hello", "world");
cout<<"ref:  "<< c <<endl;
c ="hello";

这段代码编译运行都正常:


string add(string a, string b)
{
    string c = a + b;
    return c;
}

string &&c = add("hello", "world");//clion上调试发现c和函数里面的c是同一个东西
cout<<"ref:  "<< c <<endl;
c = "hello";

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-07-10 20:45
    关注

    引自免费微信小程序:皆我百晓生

    好的,我来为你解释一下这两段代码中的左值和右值问题。

    首先,我们需要明确什么是左值和右值。在C++中,左值是指可以出现在等号左边的表达式,它具有明确的存储位置,可以持久存在并可以被赋值。而右值则是可以出现在等号右边的表达式,它表示一个临时的值,可能在表达式计算后立即销毁。在C++11中,引入了右值引用(&&)的概念,用于处理移动语义和完美转发等场景。

    现在来看你的两段代码:

    第一段代码中,你尝试返回一个局部变量的引用。局部变量是在函数内部定义的变量,当函数执行结束时,它的存储空间会被释放。因此,当你尝试返回一个局部变量的引用时,实际上是在返回一个已经销毁的存储空间的内容。这是非常危险的,因为它可能导致未定义的行为,包括程序崩溃。因此,这段代码会报SIGSEGV错误。

    第二段代码中,你返回的是一个局部变量的拷贝(使用普通的引用)。这意味着你返回的是局部变量的一个副本,而不是直接引用局部变量的内存地址。因此,即使函数执行结束,局部变量的存储空间被释放,返回的副本仍然有效。所以这段代码可以正常运行。

    当你使用右值引用时(string &&c = add("hello", "world")),你是在接收一个右值引用参数,意味着你要将临时的对象移动到另一个对象中。这里的c实际上是接收了一个临时对象的移动语义,与函数内部的局部变量是两个不同的对象。因此,即使函数执行结束,临时对象销毁,c仍然保持其有效性。这就是为什么第二段代码能够正常运行的原因。

    总结来说,第一段代码中的问题是尝试返回一个局部变量的引用,这是一个未定义的行为。而第二段代码则是返回局部变量的拷贝或使用右值引用的方式接收临时对象,因此可以正常运行。希望这能解答你的疑问。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 7月10日

悬赏问题

  • ¥15 有没有整苹果智能分拣线上图像数据
  • ¥20 有没有人会这个东西的
  • ¥15 cfx考虑调整“enforce system memory limit”参数的设置
  • ¥30 航迹分离,航迹增强,误差分析
  • ¥15 Chrome Manifest扩展引用Ajax-hook库拦截请求失败
  • ¥15 用Ros中的Topic通讯方式控制小乌龟的速度,走矩形;编写订阅器代码
  • ¥15 LLM accuracy检测
  • ¥15 pycharm添加远程解释器报错
  • ¥15 如何让子窗口鼠标滚动独立,不要传递消息给主窗口
  • ¥15 如何能达到用ping0.cc检测成这样?如图