【问题标题】:Returning an address to a local variable vs returning a pointer to a local variable将地址返回到局部变量与返回指向局部变量的指针
【发布时间】:2014-05-14 07:43:25
【问题描述】:

我的 testing.cpp 中有这个:

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;

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

【问题讨论】:

  • new 不是返回指向局部变量的指针,而是返回指向动态分配内存的指针。另一个返回指向局部变量的指针。 “局部变量的地址”不是我熟悉的短语。
  • 我被标题弄糊涂了。指针不只是包含地址吗?
  • 是的,指针保存一个地址作为它的值。但是,这不会使指针成为地址。指针是类型,地址是值。

标签: c++ pointers return memory-address


【解决方案1】:

最初误读了问题,抱歉。

第二个有效,因为您不是按引用返回,而是按值返回。如果签名是

Supp*& add(Supp& value)

那么第二个也是非法的。

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

【讨论】:

  • 为什么返回指向通过new分配的对象的指针是非法的?
  • @mah 我的错,错过了那部分。
【解决方案2】:

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

在第二个中,您将在堆上创建一个新对象,该对象将被保留,直到您手动将指针释放到其他地方为止。

【讨论】:

    【解决方案3】:

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

    可以返回new 返回的地址的原因是该地址未指向位于临时位置的对象(您的程序堆栈是通常放置局部变量的位置);相反,它来自堆内存,它将持续存在直到你处理它。此对象不依赖于分配它的代码范围,因为它不是该范围的本地对象。

    【讨论】:

      猜你喜欢
      • 2016-10-25
      • 1970-01-01
      • 2013-10-03
      • 2018-01-01
      • 2020-10-13
      • 1970-01-01
      相关资源
      最近更新 更多