【问题标题】:Distance between heap and stack堆和栈之间的距离
【发布时间】:2020-03-04 05:38:01
【问题描述】:

我正在运行一个简单的程序来显示单个进程范围内堆栈和堆之间的内存容量,并且收到一些我可能会误解的奇怪值。

我正在运行这段代码:

int main() {
  uint64_t *heap = new uint64_t;
  uint64_t stackvar; 

  uint64_t diff = &stackvar - heap;
  float size = (float) diff/ (1024 * 1024 * 1024);  // conversion to GB

  free(heap);

  return 0;
}

分配的堆变量和堆栈变量的地址值是有道理的,但我相信我误解了如何计算两者之间的内存容量,因为diff 的最终值在 16TB 范围内通过上面代码中的转换运行它。

如何有效地将这个范围转换为可理解的内存范围,或者如果我犯了错误,diff 的正确解释是什么?

【问题讨论】:

  • @tf 这个语句 uint64_t diff = &stackvar - heap;没有意义并且具有未定义的行为。
  • 我很确定是UB来获取指向不同分配对象的指针之间的差异(无论是本地数组还是动态数组)
  • 为什么16TB看起来不合理?毕竟,您正在处理的是虚拟地址,而不是物理地址。
  • freed 当你应该有 deleted 顺便说一句。这也是 UB。
  • 即使您设法获得了差异,也与容量无关。地址是虚拟的,甚至可能无法映射或访问该空间。

标签: c++ c linux memory


【解决方案1】:

&stackvar - heap 是未定义的行为。无论您从中得到什么结果都是毫无意义的。除非指针指向同一个数组或两者都 nullptr 减去它们是未定义的行为。这在[expr.add]/5中有详细说明

当两个指针表达式P和Q相减时,结果的类型是实现定义的有符号整数类型;此类型应与标头([support.types.layout])中定义为 std​::​ptrdiff_t 的类型相同。

  • 如果 P 和 Q 都计算为空指针值,则结果为 0。

  • 否则,如果 P 和 Q 分别指向同一个数组对象 x 的数组元素 i 和 j,则表达式 P - Q 的值为 i-j。

  • 否则,行为未定义。 [注意:如果值 i-j 不在 std​::​ptrdiff_t 类型的可表示值范围内,则行为未定义。 ——尾注]

强调我的

【讨论】:

    【解决方案2】:

    还要注意,进程内存不一定是连续的,指针可能实际上并不指向物理内存位置。这是由于虚拟内存和物理内存转换 What are the differences between virtual memory and physical memory? 所以在大多数情况下,你永远不会得到堆和堆栈之间的正确距离。

    【讨论】:

      猜你喜欢
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      • 2018-08-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多