在下面的代码中,为什么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 }
解决方法
这里的问题是为SomeFunc()的参数完成的副本.该副本在销毁时取消分配指针.您还需要实现复制构造函数和复制赋值运算符.见
rule of three.
编辑:
这是“扩展”的伪代码,即编译器在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
这不是确切的表示,而是概念性的解释.只需考虑编译器与代码有什么关系.