【问题标题】:What are exact requirements on automatic storage duration?自动存储时长的具体要求是什么?
【发布时间】:2011-10-29 12:14:07
【问题描述】:

以下代码取决于编译器:

int main()
{
   srand( 0 );
   if( rand() ) {
      char buffer[600 * 1024] = {};
      printf( buffer );
   } else {
      char buffer[500 * 1024] = {};
      printf( buffer );
   }
   return 0;
}

在最大堆栈大小等于 1 兆字节的系统上运行时,要么打印空字符串,要么因堆栈溢出而崩溃。

不同之处在于不同的编译器分配自动存储的方式不同。大多数编译器分配存储空间for all objects on function start,因此在上面的代码中它们分配了 600+400=1100 KB,这会导致堆栈溢出。一些编译器更聪明,他们看到这两个数组永远无法同时访问,所以他们重用相同的内存并且只分配 600 KB 并且程序运行良好。

现在标准说 (3.7/1) 存储持续时间定义了存储的最小潜在寿命,然后 (3.7.2/1) 这些对象的存储 [with自动持续时间]持续到创建它们的块存在

我不明白如何将 3.7/1 和 3.7.2/1 一起应用。一个说持续时间是最小潜力,另一个明确说持续到块存在。看起来根据第一个分配策略都是合法的,但第二个要求只使用“重用”分配策略。

3.7/1 和 3.7.2/1 如何共存?在最坏的情况下(第一种策略)分配比程序需要更多的内存是否合法?

【问题讨论】:

  • +1 个有趣的问题。
  • 我读到 3.7/1 说“根据定义,存储持续时间 指定最小值”和 3.7.2/1 说“自动变量的存储持续时间是直到封闭块退出”。所以我认为没有矛盾,任何一种策略都是允许的。 (实际上,将所有内容都保存在堆上的垃圾收集实现可能是允许的。)

标签: c++ memory memory-management duration


【解决方案1】:

“持续到”也是最小值。

【讨论】:

  • 那么我是否将这两个理解为“最短持续时间是直到块结束”?
  • 正确。请注意,即使不是这样,仍然不需要编译器在第一时间重用存储位置。
【解决方案2】:

我将 3.7/ 阅读为不同存储类(自动、静态、动态)的介绍性描述和定义,而不是作为每个存储类的实现要求......然后在 3.7.2/1 中描述了 automatich 的实现要求.

阅读 3.7.2/1 它并没有禁止它的存在时间超过块的存在时间(这只是最低限度) - 恕我直言,这是编译器实现者关于可能优化的一个机会......

【讨论】:

    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    相关资源
    最近更新 更多