我想检查我理解正确.如果我在标题中有以下内容:
public Obj * objPtr;
以及课堂上的以下内容:
void create() { //create a local variable object Obj localVar = object(); objPtr = &localVar; } void edit(){ //attempt to edit value of member pointer objPtr->edit(); }
我是否认为它永远不会起作用?因为localVar是本地的,它会在create函数之外被销毁一次,使objPtr具有空内存的地址,这意味着objPtr是一个空指针?
其次,如果我做了它会工作:
Obj localVar = new object()
或者
objPtr = new object()
我是否认为它永远不会起作用?
只是部分.你可能会很幸运,它可能会工作,但行为预计是不可预测的(或更具体地,未定义),并且肯定是代码中的错误.
原因是内容可能会或可能不会出现在指定的地址.用于create
以前的堆栈帧的内存被系统重用的点取决于几个因素,包括程序下一步尝试做什么(例如,立即调用另一个函数?声明更多变量?)和特定于体系结构的代码由编译器为它生成.
如果程序选择做某些事情导致它改变create
函数的前一个堆栈帧(例如调用另一个函数),那么如果你试图使用一个指针,你最终会得到未定义的行为&localVar
.
由于localVar是本地的,它将在create函数之外被销毁一次,使objPtr具有空内存的地址
它不会是"空"的记忆.说这是一个无效的地址可能会更准确.如果你运气好,你仍然拥有以前的价值(你等待的越多,你就越不可能幸运).不走运,你得到垃圾.变得非常不走运,你得到的东西属于别的东西(例如一些其他变量),可能会破坏事物或导致分段错误.
这意味着objPtr是一个空指针?
空指针是地址为零时,即char *ptr = 0; // same as NULL
.
其次,如果我做了它会工作:Obj localVar = new object()或objPtr = new object()
上面的代码不起作用.你需要使用指针,但localVar
不是一个.
如果你写的东西如下:
Obj *my_function() { Obj *ptrObj = new Obj(); // notice it's a pointer // ... return ptrObj; }
然后,是的,它会工作.但你应该明白为什么会有区别.
在第一种情况下,您将内容放在堆栈中,该pop
函数在函数返回后与其Obj
自身一起进行编辑.在第二种情况下,它的工作原理,因为这是堆栈上的唯一的事情就是指针到Obj
,但Obj
实例本身就是在堆,其生存函数返回时,和局部变量被删除堆栈清理.
由于您的函数现在将地址返回给使用运算符在堆中分配的对象,因此new
它将正常工作.
只需记住delete
不再需要的对象,以避免内存泄漏.