Kev*_*ith 6 c++ dangling-pointer
在下面的代码中,为什么会s1.printVal导致悬空指针错误?是不是s1直到它的销毁的对象,即它的指针,仍然可以访问?
class Sample
{
public:
int *ptr;
Sample(int i)
{
ptr = new int(i);
}
~Sample()
{
delete ptr;
}
void PrintVal()
{
cout << "The value is " << *ptr;
}
};
void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}
int main()
{
Sample s1 = 10;
SomeFunc(s1);
s1.PrintVal(); // dangling pointer
}
Run Code Online (Sandbox Code Playgroud)
Nik*_*sov 15
这里的问题是为参数做的副本SomeFunc().该副本在销毁时取消分配指针.您还需要实现复制构造函数和复制赋值运算符.见三规则.
这是"扩展"的伪代码,即编译器在main()函数中为您做的事情:
// main
addr0 = grab_stack_space( sizeof( Sample )); // alloc stack space for s1
Sample::ctor( addr0, 10 ); // call ctor of Sample
addr1 = grab_stack_space( sizeof( Sample )); // alloc stack for argument
Sample::ctor( addr1, addr0 ); // call COPY-ctor of Sample
SomeFunc( addr1 ); // call SomeFunc
Sample::dtor( addr1 ); // XXX: destruct the copy
free_stack_space( addr1, sizeof( Sample )); // free stack taken by copy
Sample::PrintVal( addr0 ); // call member func on s1
Sample::dtor( addr0 ); // destruct s1
free_stack_space( addr0, sizeof( Sample )); // YYY: free stack taken by s1
Run Code Online (Sandbox Code Playgroud)
这不是确切的表示,而是概念性的解释.只需考虑编译器与代码有什么关系.
指针成员在标记为的步骤处Sample为delete-ed XXX,然后delete在该步骤再次执行-ed YYY.