考虑下面的例子
class Foo{
public:
Foo(int i):x(i){}
int x;
};
void
bar(Foo *p2)
{
delete p2;
p2 = new Foo(2);
}
int
main()
{
Foo *p1 = new Foo(1);
cout<<p1->x;
bar(p1);
cout<<p1->x;
}
据我了解,指针变量存储在堆栈中,并包含指向它“指向”的堆上动态分配内存的地址。现在,当我将指针传递给函数时,在堆栈上创建了第二个指针,指向与第一个指针相同的内存地址。当我在 bar() 中删除 p2 并分配新内存时,p1 和 p2 应该指向不同的地址,对吧?
但是,如果我编译这段代码,我会得到 1 和 2 作为输出。这是因为 p2 设法分配了 p1 已经指向的相同内存单元,还是我遗漏了什么?
最佳答案
Is this because p2 manage to allocate the same memory cell to which p1 is already pointing to, or is there something I have missed?
您什么也没错过。您已正确识别出此程序的行为是未定义。根据定义,它可以打印任何内容,包括 2
。
在您的运行中,只有巧合(而且很可能是您确定的巧合)导致它打印 2
。您可以通过在 delete
之后和现有 new
之前添加 new int(47)
来破坏巧合链。
如果您希望程序按照它的方式运行,但通过定义的行为,您可以对 bar
的定义进行以下小改动:
void
bar(Foo*& p2)
这传递参数通过引用而不是通过值。通过这样做,对 bar
内的变量 p2
的更改反射(reflect)在 `main.js 内的 p1
中。
关于c++ - 将指针作为参数传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11480413/