考虑
Foo* f = new Foo();
delete f;
Foo* g = f;
由于我读到了一个我不拥有的内存指针,最终语句现在是未定义的吗?对我而言,它违反了一个过去的结束规则,所以它应该是。
请注意
Foo* f;
Foo* g = f;
未定义。
答案 0 :(得分:12)
由于我读到了一个我不拥有的内存指针,现在是否定义了最终语句?
不,声明
Foo* g = f;
本身不会调用未定义的行为。指针值的复制操作可以随时安全地完成。
但是,在f
被删除后,进一步使用指针g
或f
进行解除引用将导致未定义的行为。
您甚至可以安全地使用这些指针值,例如记录目的:
std::cout << "g = " << g << std::endl;
请注意
Foo* f; Foo* g = f;
未定义。
这个假设是错误的。它既不是未定义的行为,同样它取消引用未初始化的指针是未定义的行为,普通的赋值不是。
答案 1 :(得分:3)
您可以复制指针,没有什么可以阻止您这样做,但指针是取消分配内存所以不应该使用它。如果您确实使用它,那么您可以直接进入未定义的行为,因此这不是一个好主意。
由于f
指针本身仍在堆栈中,因此您可以无需担心地复制它。这只是一件奇怪的事情。
答案 2 :(得分:1)
这可能不是有用的代码,但是如果你把它想象成删除后,f
包含一个陈旧的指针。您的示例将过时指针复制到g
。在尝试通过陈旧指针访问带有g
的内容之前,您没有做任何非常糟糕的事情。