我有以下行为怪异的代码。到目前为止,我理解的流程是,display(line);
将调用复制构造函数Line::Line(const Line &obj)
,并且line
的引用将被传入。但是cout<<"[origin] *ptr="<<*obj.ptr<<endl;
将打印[origin] *ptr=32767
而不是[origin] *ptr=10
。
更奇怪的是,如果我取消对// int x=3;
的注释,它将正确打印,但我真的不知道为什么。
您可以在以下位置找到可执行代码:https://www.onlinegdb.com/pjbPO0X1f
#include <iostream>
using namespace std;
class Line
{
public:
int getLength( void );
Line( int len );
Line( const Line &obj);
private:
int *ptr;
};
// constructor
Line::Line(int len)
{
ptr=&len;
cout<<"*ptr="<<(*ptr)<<endl;
}
// copy constructor
Line::Line(const Line &obj)
{
// int x=3;
cout<<"[origin] *ptr="<<*obj.ptr<<endl;
ptr = new int;
*ptr = *obj.ptr; // copy
}
int Line::getLength( void )
{
return *ptr;
}
void display(Line obj)
{
cout << "line=" << obj.getLength() <<endl;
}
int main( )
{
Line line(10);
display(line);
return 0;
}
您的程序调用未定义的行为(UB(。当你的构造函数完成:
Line::Line(int len)
{
ptr=&len;
cout<<"*ptr="<<(*ptr)<<endl;
} // ptr is dangling
指针ptr
指向不再存在的局部变量len
。ptr
现在处于悬空状态,任何对其取消引用的尝试都会调用UB。
你的程序可以做任何事情。你也可以看到一些奇怪的结果,比如添加CCD_;行为正确";。不要担心为什么会发生这种情况,这只是UB的结果。
这是一个常见的错误(尽管这是它的一个奇怪版本(。
这个代码是错误的
// constructor
Line::Line(int len)
{
ptr=&len;
cout<<"*ptr="<<(*ptr)<<endl;
}
使得ptr
指向len
,但是len
是局部变量。当构造函数退出时,它将被销毁。这意味着您有一个指向已不存在的对象的指针。有时这被称为悬挂指针。
然后在代码的后面使用这个指针
cout<<"[origin] *ptr="<<*obj.ptr<<endl;
由于指针现在无效,因此效果是不可预测的。
使指针变得困难的许多事情之一是,指针的生存期和它所指向的对象的生存期根本没有任何联系。这取决于你确保你的指针总是指向仍然"活着"的对象。