首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >向局部变量返回地址与返回指向局部变量的指针

向局部变量返回地址与返回指向局部变量的指针
EN

Stack Overflow用户
提问于 2014-04-02 19:40:55
回答 3查看 137关注 0票数 1

我在我的testing.cpp里有这个:

代码语言:javascript
运行
复制
class Supp{
public:
virtual Supp* add(Supp& val) = 0;
};

class SubA : public Supp{
public:
int val;

SubA(int a){
    val = a;
}
int getVal(){
    return val;
}
Supp* add(Supp& value){
    SubA& a = dynamic_cast<SubA&>(value);
    int tempVal = a.getVal();
    int sum = val + tempVal;
    SubA b =SubA(sum);
    return &b;
}
};

还有那些线

SubA b = SubA(sum); return &b;

提供和错误,因为它将地址返回给一个局部变量,这是非常糟糕的,所以我将它更改为

SubA* b =new SubA(sum); return b;

它工作正常,没有错误,但这不是基本上相同的事情吗?为什么这对编译器是合法的,而以前的版本却不合法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-02 19:48:58

将地址返回给局部变量是非法的,因为一旦函数返回,局部变量就不再存在,因此您将返回一个已知不再有效的地址。(对象可能仍然在那里,但是它的析构函数已经被调用了,它占用的内存将在某个时候被用于其他的东西--也许是在下一个子程序调用中。)

可以返回new返回的地址的原因是,地址不是指向一个驻留在临时位置的对象(程序堆栈通常位于局部变量的位置),而是来自堆内存,堆内存将一直保存到您将其释放为止。该对象不依赖于分配给它的代码范围,因为它不是该作用域的本地对象。

票数 3
EN

Stack Overflow用户

发布于 2014-04-02 19:48:02

在第一个示例中,您的局部变量被分配到堆栈上(在堆栈中,所有局部变量在其作用域的持续时间内),并且在返回到调用函数时将立即被释放。因此,当您离开函数时,返回的指针将无效。

在第二个过程中,您将在堆中创建一个新对象,在此对象将被保留,直到您手动地将指针释放到另一行的某个地方。

票数 1
EN

Stack Overflow用户

发布于 2014-04-02 19:43:38

一开始误解了问题,抱歉。

第二种方法之所以有效,是因为您返回的不是引用,而是值。如果签名是

代码语言:javascript
运行
复制
Supp*& add(Supp& value)

那么第二个问题也是非法的。

请记住,具有自动存储持续时间的对象在关闭}时会被销毁。因此,函数返回后,对象b不再可访问。它的副本。如果您按值返回,则原始内容将消失,但您将保留副本。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22821372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档