比较悬空指针合法吗?

2023-11-23

比较悬空指针合法吗?

int *p, *q;
{
    int a;
    p = &a;
}
{
    int b;
    q = &b;
}
std::cout << (p == q) << '\n';

注意两者如何p and q指向已经消失的物体。这合法吗?


介绍:第一个问题是使用价值是否合法p at all.

After a已被摧毁,p获得所谓的无效的指针值。引用自N4430(有关 N4430 状态的讨论,请参阅下面的“注释”):

当到达存储区域的持续时间结束时,表示已释放存储的任何部分的地址的所有指针的值变为无效的指针值.

N4430 的同一部分也介绍了使用无效指针值时的行为(几乎相同的文本出现在 C++14 [basic.stc.dynamic.deallocation]/4 中):

通过无效指针值进行间接寻址以及将无效指针值传递给释放函数具有未定义的行为。对无效指针值的任何其他使用实现定义的行为.

[ 脚注:某些实现可能会定义复制无效的指针值会导致系统生成的运行时错误。 ——脚注结束]

因此,您需要查阅实现的文档以了解此处应该发生什么(自 C++14 起)。

期限use在上面的引用中means需要左值到右值的转换,如 C++14 [conv.lval/2] 中所示:

当左值到右值转换应用于表达式 e,并且 [...] 左值引用的对象包含无效指针值时,该行为是实现定义的。


History:在 C++11 中这样说不明确的而不是实现定义的;它被改变了DR1438。请参阅这篇文章的编辑历史以获取完整的引用。


申请到p == q:假设我们在 C++14+N4430 中接受了评估的结果p and q是实现定义的,并且实现没有定义硬件陷阱的发生; [expr.eq]/2 说:

如果两个指针都为空、都指向同一函数或都表示相同的地址 (3.9.2),则它们比较相等,否则它们比较不相等。

因为它是实现定义的,所以什么时候会获得什么值p and q进行评估后,我们无法确定这里会发生什么。但它必须是实现定义的或未指定的。

在这种情况下,g++ 似乎表现出未指定的行为;取决于-O切换我可以让它说1 or 0,对应于是否重复使用相同的内存地址b after a已被摧毁。


关于 N4430 的注意事项:这是针对 C++14 的缺陷解决方案的提议,尚未被接受。它清理了围绕对象生命周期、无效指针、子对象、联合和数组边界访问的大量措辞。

在 C++14 文本中,在 [basic.stc.dynamic.deallocation]/4 及后续段落下定义无效的指针值出现时delete用来。然而,没有明确说明相同的原理是否适用于静态或自动存储。

[basic.compound]/3 中有一个“有效指针”的定义,但它太模糊了,无法明智地使用。[basic.life]/5(脚注)引用相同的文本来定义指向对象的指针的行为静态存储持续时间,这表明它适用于所有类型的存储。

在 N4430 中,文本从该部分向上移动了一级,以便它明确适用于所有存储持续时间。附有注释:

起草注意事项:这应该适用于所有可以结束的存储持续时间,而不仅仅是动态存储持续时间。在支持线程或分段堆栈的实现上,线程和自动存储的行为方式可能与动态存储相同。


我的想法:除了说之外,我看不到任何一致的方式来解释该标准(N4430 之前的版本)p获取无效的指针值。除了我们已经看过的内容之外,该行为似乎没有被任何其他部分所涵盖。因此,我很高兴将 N4430 措辞视为代表本例中标准的意图。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

比较悬空指针合法吗? 的相关文章

随机推荐

  • 使用“SELECT”调用函数

    我偶尔会遇到这样的例子SELECT INTO FROM DUAL用于调用函数 例如 SELECT some function INTO a variable FROM DUAL 使用 而不是 a variable some function
  • 访问自动属性 ​​- C#

    自动属性被添加到 net 3 中的语言中 无论如何 使用以下代码创建一个 私有 字段 public string foo get set 是否有可能真正获得对此私有字段的任何形式的引用 我想做类似的事情 public string foo
  • 为什么 Rust 链接器在增量构建时没有更快?

    我是 Rust 的新手 我试图理解为什么 Rust 不能更快地构建 我特别讨论的是最常见的情况 其中我对一个源文件做了一个小更改 然后我需要等待几秒钟cargo build做它的工作 即使我的应用程序代码非常小 如果我添加对 MySQL 和
  • TreeMap 按值排序

    我想编写一个比较器 它可以让我按值而不是默认的自然顺序对 TreeMap 进行排序 我尝试了这样的事情 但无法找出出了什么问题 import java util class treeMap public static void main S
  • 如何使用Powershell或其他工具(递归)获取所有AD用户组?

    我试图在我使用的 Powershell 中获取用户所属的所有组 甚至是嵌套的组 重复地 Get ADUser
  • x86 操作码是任意的吗?

    x86 操作码是任意的吗 有没有理由hlt是 0xf4 并且nop是0x90吗 该架构的早期版本 8008 8080 是使用极少量的晶体管 逻辑门来实现的 当时 我确信设计者以易于解码的方式选择了操作码和指令格式 例如 最少的门数 这些说明
  • 如何在hadoop中执行MapReduce作业期间在控制台上打印

    我想在控制台上执行后打印 地图 的每一步 就像是 System out println 第一步完成 System out println 第二步完成 等等 是否有一个特殊的命令可以做到这一点 或者根本不可能 因为 System out pr
  • Flutter - 删除 dart 中的转义序列

    要将 API 响应字符串解码为 JSON json decode 工作正常 这将解析类似于以下内容的 JSON 字符串 Response Responsecode 1 Response Success 但就我而言 响应采用序列化形式 例如
  • SQL语法多重连接?

    我有两个表 Transaction 和 Master 事务表显示了起始和结束活动 ID 主控显示活动 ID 和名称 from 和 to id 使用相同的主表来关联活动 id 和名称 我想做的是采用不同的 from 和 to 值并用关联的名称
  • 从谷歌地图中删除 HeatmapLayer

    我正在使用 HeatmapLayer apihttps developers google com maps documentation javascript layers JSHeatMaps 我像这样生成热图 heatmap new g
  • 在C#中使用FtpWebRequest时设置端口号

    当我尝试使用 VS2008 作为调试器从 C 代码 FTP 到我的 Win 2008 服务器时 我不断收到异常 我的测试类如下所示 public class FTP private string ftpServerIP 192 168 10
  • 比较 BigDecimal

    我有以下两个 BigDecimal 对象 BigDecimal one new BigDecimal 3 0 BigDecimal two new BigDecimal 3 00 System out println one scale 0
  • 三角测量和直接线性变换

    按照 Hartley Zisserman 的多视图几何算法 12 最佳三角测量方法 p318 我得到了相应的图像点 xhat1 和 xhat2 步骤 10 在步骤11中 需要计算3D点Xhat 其中一种方法是直接线性变换 DLT 在 12
  • 如何从Java中的日期获取世纪

    如何从Java中的日期获取当前世纪 例如日期 06 03 2011 根据格式 MM dd yyyy 我怎样才能从这个日期使用当前世纪SimpleDateFormat 哈利 莱姆发布的内容略有变化 他的逻辑并不完全正确 1901 年是 20
  • 为什么要包括警卫?

    包括定义的警卫here 用于防止在编译时两次加载相同的代码 为什么我的编译器 GCC 无法检测到它正在加载相同的代码两次并具有合理的默认行为 仅仅是因为您可能希望编译器加载该文件两次 请记住 那个 include只需加载一个文件并将其内容放
  • 我可以优化 Mercurial 克隆吗?

    我的 Mercurial 克隆变得非常慢 可能是由于磁盘碎片所致 有没有办法优化它 最明显的方法是创建一个新克隆 然后将我的 MQ 保存的捆绑包 hgrc 等复制到新克隆并删除旧克隆 但似乎有人以前遇到过这个问题并进行了扩展来做到这一点 如
  • 如何使用 std::rel_ops 自动提供比较运算符? [复制]

    这个问题在这里已经有答案了 如何获得运营商 gt gt lt and from and
  • 如何在 Python 中检测文件是否为二进制(非文本)?

    在 Python 中如何判断文件是否是二进制 非文本 我正在 Python 中搜索大量文件 并不断在二进制文件中获取匹配项 这使得输出看起来非常混乱 我知道我可以使用grep I 但我对数据的处理超出了 grep 允许的范围 过去 我只会搜
  • “此链接已停用,因为它未嵌入 JSF 表单中。”

    当我使用以下命令链接时
  • 比较悬空指针合法吗?

    比较悬空指针合法吗 int p q int a p a int b q b std cout lt lt p q lt lt n 注意两者如何p and q指向已经消失的物体 这合法吗 介绍 第一个问题是使用价值是否合法p at all A