临时存储时间的要求是什么?

时间:2011-08-19 07:31:36

标签: c++ memory memory-management duration

请考虑以下代码:

class Test() {
public:
    Test()
    {
       memset( buffer, 0, sizeof( buffer ) );
    }
    void Process()
    {
       printf( buffer );
    }
private:
    char buffer[1000];
};

int main()
{
    Test().Process();
    char buffer[1000] = {};
    print( buffer );
    return 0;      
}

我无法推断出main中的buffer是否允许重用先前由class Test临时对象占用的内存。根据标准自动存储(3.7.2 / 1)must persist for at least until the block ends

我找不到强制临时对象使用自动存储的措辞,除了6.6 / 2,其中描述了一个跳转语句,并且说明退出范围[...],析构函数(12.4)调用具有自动存储持续时间(3.7.2)(命名对象或临时值)的所有构造对象,这似乎意味着临时使用自动存储。

是否需要临时使用自动存储?上面代码中的main中的局部变量是否允许重用以前由临时占用的内存,还是应该使用不同的存储?

5 个答案:

答案 0 :(得分:6)

临时的生命周期(除非绑定到const&)延伸到完整表达式的末尾。在你的情况下,main中的第一行。允许编译器重用相同的内存,但它是否具有实现细节(即实现质量

  

12.2 [class.temporary]

     

/ 3 [...]临时对象作为评估的最后一步被销毁   完整表达式(1.9)(词法上)包含创建它们的点。[...]

     

/ 4有两种情况下,临时表在与完整表达式结束时不同的点被销毁。第一个上下文是表达式作为定义对象的声明符的初始值设定项。 [...]

     

/ 5第二个上下文是指引用绑定到临时引用。

由于您既不是例外,Test临时属于第一类,已销毁作为评估第一行的最后一步。

答案 1 :(得分:3)

3.7.2 / 1专门讨论了块范围变量。那些存储必须持续存储。但是,正如您所发现的,临时工具具有自动存储持续时间,但不是块范围变量。 (见3.3.3,块范围与名称相关)。

答案 2 :(得分:2)

语法Test()创建一个临时语句。这与名为

的对象不同
Test iHaveAName;

命名对象具有块持续时间;它将一直存在直到阻止结束。临时表达持续时间;当表达式结束时它将被销毁。

因此,如果您执行Test().Process(),则Test()临时用户将活得足够长,Process()可以完成。

答案 3 :(得分:1)

Test实例一直存在;那里。是否未指定buffer是否重用用于Test实例的存储。 AFAIK,标准中没有任何内容阻止编译器重用该空间。

答案 4 :(得分:0)

它是实现定义的。智能编译器可以通过对齐堆栈指针来优化代码,以便buffer可以重用内存。