正在读取指向已删除内存未定义行为的指针

Is reading a pointer to deleted memory undefined behavior?

本文关键字:未定义 指针 内存 删除 读取 取指      更新时间:2023-10-16

考虑

Foo* f = new Foo();
delete f;
Foo* g = f;

由于我读取了指向我不拥有的内存的指针,因此最终语句现在未定义吗?对我来说,它违反了"一到终"的规则,所以它应该是。

请注意,

Foo* f;
Foo* g = f;

未定义。

由于我读取了指向我不拥有的内存的指针,因此最终语句现在未定义吗?

不,声明

Foo* g = f;

本身不会调用未定义的行为。指针值的复制操作可以随时安全地完成。

但是,进一步使用指针fg取消引用将导致删除f后出现未定义的行为

您甚至可以安全地使用这些指针值,例如用于日志记录目的:

std::cout << "g = " << g << std::endl;

请注意,

Foo* f;
Foo* g = f;

未定义。

这种假设是错误的。它既不是未定义的行为,它再次取消引用未初始化的指针是未定义的行为,普通赋值不是。

您可以复制指针,没有什么可以阻止您这样做,但是指针指向已解除分配的内存,因此不应使用它。如果你确实使用它,你就会直接进入不确定的行为,所以这真的不是一个好主意。

由于f指针本身仍在堆栈上,因此您可以放心地复制它。这只是一件奇怪的事情。

它可能不是有用的代码,但如果您将其视为删除后,f包含一个过时的指针。 您示例将该过时的指针复制到 g 。 在你尝试通过过时的指针访问g的东西之前,你并没有做任何非常糟糕的事情。