【问题标题】:What if object is located at highest address possible如果对象位于可能的最高地址怎么办
【发布时间】:2016-09-01 18:02:26
【问题描述】:

如果static_cast< std::uintptr_t >(&obj) == std::numeric_limits< std::uintptr_t >::max() - sizeof(obj) + 1 怎么办?比如说,obj 是连续 STL 容器(或本机数组)中的最后一个元素,使用迭代器范围的 STL 算法应该如何处理它?我确信连续容器的迭代器(甚至是调试版本)的设计方式是,它们使用过去元素的地址(不可取消引用,但有效)。

我知道,操作系统的常见设计是在可能的最高地址分配堆栈,并且对于统一内存系统,放置第一个调用函数的返回地址(至少 main)。但是有些系统可以在任何地址上分配堆栈(对于每个进程,我想要)。

【问题讨论】:

  • 获得“最后一个”地址的唯一方法是操作系统是否会将其映射到您的进程,这将是一个非常糟糕的操作系统,因为“一个超出结尾”就是这样标记某事结束的常用方法。
  • 这个问题似乎无关紧要。该标准要求末端迭代器存在并起作用。因此,如果系统无法处理最后一个元素为最高uintptr_t 值的数组的结束迭代器,那么实现 put 这样的数组是非法的元素放在首位。
  • 如果修改需要重新分配/移动数据,迭代器就会失效。
  • @myaut 我可以移动实际数据并将对它的引用更改为我自己的迭代器实现。我认为,双重间接和侵入式迭代器并不违法。

标签: c++ memory stl iterator containers


【解决方案1】:

这是不可能的,因为必须至少有一个地址可用于过去的迭代器。

所以实现必须以某种方式解决这个问题,比如不在内存顶部分配对象(但可能是代码),或者为更多地址留出空间。

【讨论】:

  • 是内存模型定义的引用吗?
  • @Orient:没有什么可引用的。这是需要存在结束迭代器的结果。实现不能做使结束迭代器不可能的事情。
  • @NicolBolas 如果系统使用 ASLR 并且我的代码是 PIC,那么实现如何证明最后一个字节(又是放入 .text 部分的静态数据(或datum))不在可能的最大地址。比如说,代码段的大小是 4096 的倍数,硬件是 x86/x64——页面可以分配到最高的虚拟地址。否则我不能在 x86 上为 C++ 使用 4G 内存的最后一页,不是吗?
  • @Orient: "否则我不能在 x86 上为 C++ 使用 4G 内存的最后一页,不是吗?" 以你的例子来说,它会更准确说 ASLR 不应该尝试将静态数据段加载到最后一个虚拟地址页中。唯一会影响的“STL 对象”是array;所有其他都是动态分配的。
  • @Orient:你说“C++ 问题”好像指针算术和边界是 C++ 独有的。
猜你喜欢
  • 2019-12-07
  • 2011-04-18
  • 1970-01-01
  • 2021-07-29
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
相关资源
最近更新 更多