C++ MFC缺少const char *变量

C++ MFC缺少const char *变量,c++,debugging,mfc,const-char,C++,Debugging,Mfc,Const Char,我在按钮点击方法中有一个简单的代码: std::stringstream ss; unsigned counter = 0; while(true) { ss.clear(); ss << DEFAULT_USER_CONFIG_NAME << " " << ++counter; const char* name = ss.str().c_str(); MessageBox(name); /* ... while br

我在按钮点击方法中有一个简单的代码:

std::stringstream ss;
unsigned counter = 0;
while(true)
{
    ss.clear();
    ss << DEFAULT_USER_CONFIG_NAME << " " << ++counter;
    const char* name = ss.str().c_str();
    MessageBox(name);

    /* ... while break condition */
}
我在调试器中发现,局部变量名不是createdat,至少它没有显示在调试器中。有没有线索说明为什么它在直接通过时起作用,而在其他情况下失败?另外,当我将name强制转换为CString时,它在IsEmpty检查时返回true。

表达式ss.str创建了一个临时std::string对象。因此,存储c_str的结果指向一个临时的内存,它很快就会变成一个悬空的指针。一旦满表达式语句

const char* name = ss.str().c_str();
//                                 ^ this is where the temporary ss.str() gets destroyed.
评估后,临时文件将被销毁

您已经知道如何解决这个问题,将创建临时表达式的表达式放在使用它的完整表达式中。这将延长临时表达式的生存期,直到完整表达式结束:

MessageBox(ss.str().c_str());
//                          ^ this is where the temporary ss.str() gets destroyed.
以下说明了事件的顺序。让我们只定义几个占位符类和函数:

void messagebox(const char*) {
    cout << "messagebox()" << endl;
}

struct tmp {
    tmp(const char* content) : content(content) { cout << "tmp c'tor" << endl; }
    ~tmp() { cout << "tmp d'tor" << endl; }
    const char* c_str() { return content.c_str(); }
private:
    string content;
};

struct ss {
    tmp str() { return tmp("test"); }
};
生成以下输出:

而第二个版本

ss s;
messagebox(s.str().c_str());
更改输出中的顺序:

表达式ss.str创建一个临时std::string对象。因此,存储c_str的结果指向一个临时的内存,它很快就会变成一个悬空的指针。一旦满表达式语句

const char* name = ss.str().c_str();
//                                 ^ this is where the temporary ss.str() gets destroyed.
评估后,临时文件将被销毁

您已经知道如何解决这个问题,将创建临时表达式的表达式放在使用它的完整表达式中。这将延长临时表达式的生存期,直到完整表达式结束:

MessageBox(ss.str().c_str());
//                          ^ this is where the temporary ss.str() gets destroyed.
以下说明了事件的顺序。让我们只定义几个占位符类和函数:

void messagebox(const char*) {
    cout << "messagebox()" << endl;
}

struct tmp {
    tmp(const char* content) : content(content) { cout << "tmp c'tor" << endl; }
    ~tmp() { cout << "tmp d'tor" << endl; }
    const char* c_str() { return content.c_str(); }
private:
    string content;
};

struct ss {
    tmp str() { return tmp("test"); }
};
生成以下输出:

而第二个版本

ss s;
messagebox(s.str().c_str());
更改输出中的顺序:


所有这些都符合标准。第一个版本的问题是ss.str在MessageBoxname调用之前被破坏。你有什么问题吗?都是按照标准的。第一个版本的问题是ss.str在MessageBoxname调用之前被破坏。你有什么问题吗?谢谢你的回答。你知道为什么调试器根本不显示变量名吗?[Visual Studio 2010]@Arrekin:在第一个代码段中,本地和自动选项卡下都应显示名称。如果没有显示,我不知道为什么。在调试构建中,它应该指向一个内容为0xCD的字符串,标记为释放的内存。如果您需要检查未自动显示的变量,您可以随时添加。谢谢您的回答。你知道为什么调试器根本不显示变量名吗?[Visual Studio 2010]@Arrekin:在第一个代码段中,本地和自动选项卡下都应显示名称。如果没有显示,我不知道为什么。在调试构建中,它应该指向一个内容为0xCD的字符串,标记为释放的内存。如果您需要检查未自动显示的变量,则始终可以添加一个。