2016-07-25 54 views
6

我对下面的C++代码有点糊涂了:初始化

#include <iostream> 

using namespace std; 

void test(const string& str) 
{ 
    static const char * const c = str.c_str(); 
    cout << c << endl; 
} 

int main(int argc, char* argv[]) 
{ 
    test("Hello"); 
    test("Nooo"); 
    return 0; 
} 

由于变量c被声明为staticconst,应该不是这个只进行一次初始化,并保持其初始值直到过程完成?根据这个道理,我期待下面的输出:

Hello 
Hello 

但我得到:

Hello 
Nooo 

你能解释,为什么变量c的价值已经过两次功能之间修改调用,即使它是一个const变量?

回答

14

您的程序有未定义的行为

当传递到"hello"test,则创建临时std::string对象,并从该字符串c构造(这仅仅是一个指向字符串对象的数据)。

函数调用结束时,临时std::string对象被销毁,c成为悬挂指针。再次使用它是未定义的行为。

就你而言,第二个临时对象的数据std::string与第一个对象的数据具有完全相同的内存地址,因此c指向该数据。这是不能保证的。

+0

其实它不是未定义的。 **解除引用**它是未定义的。由于它在解引用时总是有一个有效的地址,所以它是一个有效的程序。 – StoryTeller

+3

@StoryTeller,'cout << c << endl;'提供指针的引用。 –

+1

@StoryTeller输出操作符使用解引用。 –

1

您的代码中有未定义的行为,因此这些结果可能会有所不同。 UB是因为调用test("Hello");创建了一个临时值,然后将其分配给静态局部变量。这个临时函数在调用结束后被删除,所以测试函数中的指针是悬空的。如果你使用它,那么你有未定义的行为。

内存管理器有可能重用相同的内存区域,以便在结果中看到Hello和Nooo。