绑定到已销毁堆栈变量的 const 引用的生命周期
Lifetime of const references bound to destroyed stack variable
我想知道它是否偶然指向绑定到已销毁堆栈变量的 const 引用的指针可以正常工作。
我读到 const 引用生命周期在 上延长,所以这是 "normal" const 引用有效但在存储引用的 ctor 结束时应该被销毁,不是吗?
const 引用的生命周期是否也延长了,因为我在指针中检索了它的地址,还是这纯粹是运气?
#include <iostream>
class Storage
{
public:
Storage(const int& ref)
{
p = &ref;
}
const int* Get() const
{
return p;
}
private:
const int* p;
};
int main()
{
Storage* s = nullptr;
{
int someValue = 42;
std::cout << &someValue << std::endl;
s = new Storage(someValue);
}
const int* p = s->Get();
std::cout << p << std::endl;
std::cout << *p << std::endl;
}
它也在使用结构 Live example
#include <iostream>
struct Dummy
{
int value;
};
class Storage
{
public:
Storage(const Dummy& ref)
{
p = &ref; // Get address of const reference
}
const Dummy* Get() const
{
return p;
}
private:
const Dummy* p;
};
int main()
{
Storage* s = nullptr;
{
Dummy dummy;
dummy.value = 42;
std::cout << &dummy << std::endl;
s = new Storage(dummy);
}
const Dummy* p = s->Get();
std::cout << p << std::endl;
std::cout << p->value << std::endl;
}
您的 s
变量确实有一个悬空指针,因为 someValue
已超出范围。因此,您的代码表现出未定义的行为。
您关于 "const reference lifetime is extended on rvalues" 的评论在某些情况下是正确的,但 someValue
是一个 lvalue。
编译器可能会在一开始就为所有局部变量分配堆栈 space,因此即使超出范围,someValue 仍位于内存中的同一位置。当然,不同的编译器可能会做一些不同的事情,并且它可能会被后续的局部变量覆盖。
对于你的第二个例子,如果你写了一个 ~Dummy(){ value=0; },那就不行了,证明dummy object的生命周期没有被延长
我想知道它是否偶然指向绑定到已销毁堆栈变量的 const 引用的指针可以正常工作。
我读到 const 引用生命周期在
const 引用的生命周期是否也延长了,因为我在指针中检索了它的地址,还是这纯粹是运气?
#include <iostream>
class Storage
{
public:
Storage(const int& ref)
{
p = &ref;
}
const int* Get() const
{
return p;
}
private:
const int* p;
};
int main()
{
Storage* s = nullptr;
{
int someValue = 42;
std::cout << &someValue << std::endl;
s = new Storage(someValue);
}
const int* p = s->Get();
std::cout << p << std::endl;
std::cout << *p << std::endl;
}
它也在使用结构 Live example
#include <iostream>
struct Dummy
{
int value;
};
class Storage
{
public:
Storage(const Dummy& ref)
{
p = &ref; // Get address of const reference
}
const Dummy* Get() const
{
return p;
}
private:
const Dummy* p;
};
int main()
{
Storage* s = nullptr;
{
Dummy dummy;
dummy.value = 42;
std::cout << &dummy << std::endl;
s = new Storage(dummy);
}
const Dummy* p = s->Get();
std::cout << p << std::endl;
std::cout << p->value << std::endl;
}
您的 s
变量确实有一个悬空指针,因为 someValue
已超出范围。因此,您的代码表现出未定义的行为。
您关于 "const reference lifetime is extended on rvalues" 的评论在某些情况下是正确的,但 someValue
是一个 lvalue。
编译器可能会在一开始就为所有局部变量分配堆栈 space,因此即使超出范围,someValue 仍位于内存中的同一位置。当然,不同的编译器可能会做一些不同的事情,并且它可能会被后续的局部变量覆盖。
对于你的第二个例子,如果你写了一个 ~Dummy(){ value=0; },那就不行了,证明dummy object的生命周期没有被延长