[英]What happens with return value?
So I have 2 classes for this example: 所以这个例子我有2个类:
E
, which prints a message when it is destroyed + can store integer value E
,在销毁时打印消息+可以存储整数值
T
, which stores instance of E
and can return it through a method T
,存储E
实例并可以通过方法返回它
Code: 码:
class E
{
public:
E();
~E();
int test;
};
E::E(){}
E::~E()
{
std::cout << "E is destroyed" << std::endl;
}
///////////////////////////////////////////
class T
{
public:
T();
~T();
E data;
E get();
};
T::T(){}
T::~T(){}
E T::get()
{
return this->data;
}
///////////////////////////////////////////
int main()
{
E e;
e.test = 2;
T t;
t.data = e;
E* e2;
{
e2 = &(t.get());
std::cout << "end of block" << std::endl;
}
std::cout << e2->test;
}
Result of running my code is: 运行我的代码的结果是:
E is destroyed
end of block
which means that some instance of E
is destroyed before reaching the end of {}
这意味着
E
一些实例在到达{}
结束之前被销毁
Questions: 问题:
1. I experimented a bit. 我试验了一下。 Is it correct that
t.get()
value in e2 = &(t.get());
e2 = &(t.get());
中的t.get()
值是否正确e2 = &(t.get());
line is destroyed immediately because it was not assigned by value to any variable? line被立即销毁,因为它没有按值分配给任何变量?
2. If this value is destroyed, that means that e2
pointer is invalid. 2.如果此值被销毁,则表示
e2
指针无效。 But std::cout << e2->test;
但是
std::cout << e2->test;
line still prints saved integer value. line仍然打印保存的整数值。 Is pointer still valid somehow or this data just occassionally stayed at this place of memory?
指针在某种程度上是否仍然有效,或者这些数据只是暂时停留在这个记忆的地方?
The original code won't compile by GCC because the function 原始代码不会由GCC编译,因为该函数
E T::get()
{
return this->data;
}
returns value. 返回值。 When you assign the pointer
e2 = &(t.get());
当你指定指针
e2 = &(t.get());
in the block, it makes a temporary copy of data
. 在块中,它生成临时的
data
副本。 After you exit from the block, when you reference the pointer e2
, it no longer points to the actual variable because the temporary variable is out of scope. 退出块后,当您引用指针
e2
,它不再指向实际变量,因为临时变量超出了范围。 So in order to correct this, you can modify the code to return a reference to data
field of class T
: 因此,为了纠正这个问题,您可以修改代码以返回对类
T
data
字段的引用:
E& T::get()
{
return data;
}
After that when you run the code again, you will see: 之后,当您再次运行代码时,您将看到:
end of block
2
E is destroyed
E is destroyed
Note that the two E is destroyed
is due to the fact that there are two E
instances, one for e
, and the other for t.data
because the code t.data = e;
注意,两个
E is destroyed
的原因是有两个E
实例,一个用于e
,另一个用于t.data
因为代码t.data = e;
will invoke the copy constructor of class E
. 将调用
E
类的复制构造函数。 Therefore finally there are two E
objects get destructed when the program exits. 因此,当程序退出时,最终会有两个
E
对象被破坏。
By default, memory that is freed is not set to a specific value. 默认情况下,释放的内存未设置为特定值。 Thus, it keeps the last value it had.
因此,它保留了它的最后一个值。 What is happening is that the address of your copy of t->data is stored in e2.
发生的事情是你的t->数据副本的地址存储在e2中。 Then, the compiler frees said copy because you are not using it anymore.
然后,编译器释放所述副本,因为您不再使用它。 Thus you have a call to the destructor.
因此,您可以调用析构函数。
However, you are indeed keeping the values in memory so your pointer can still access them. 但是,您确实将值保留在内存中,以便指针仍然可以访问它们。 (But i am guessing that with valgrind that is spitting out an invalid read.)
(但我猜测,valgrind会吐出无效的读数。)
So yes, your pointer is indeed invalid, however it still can access the data. 所以,是的,你的指针确实无效,但它仍然可以访问数据。
Rephrased to answer logically your questions : 重新回答逻辑上你的问题:
1) It's a copy and not assigned so destroyed immediately. 1)这是一份副本,并没有立即销毁。
2) The values exist at the address however the address is considered invalid and can lead to memory issues (Segmentation fault for example) 2)值存在于地址但是地址被视为无效并且可能导致内存问题(例如,分段错误)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.