我在项目中遇到过同样的情况。
以下代码类似地被复制。
#include <iostream>
#include <vector>
using namespace std;
class METHOD
{
public:
vector<METHOD*> m_arg;
string name;
string getName()
{
return name;
}
METHOD()
{
}
METHOD(string n)
{
name = n;
}
};
class PF : public METHOD
{
public:
PF(){};
};
void main()
{
PF p;
p.m_arg.push_back(new METHOD(string("a")));
p.m_arg.push_back(new METHOD(string("b")));
p.m_arg.push_back(new METHOD(string("c")));
for(int i = 0 ; i < (int)p.m_arg.size() ; ++i)
{
const char* ccs = p.m_arg[i]->getName().c_str(); //PROBLEM POINT
size_t ss = strlen(ccs);
}
}
问题是//问题点
无法将 c_str()的返回地址分配给 const char * ccs 。
在调试器中, css 分配了 c_str()的返回内存地址,但 css 的值为“”,并且与“”相同
但下一个代码将按预期工作。
string str("ok");
const char* ckk = str.c_str();
在此代码后, ckk 指向 str.c_str()返回的地址后,并且 ckk 在调试器中的值为“ok”
在std::wstring,wchar_t,unicode中发生相同的问题。
为什么会出现此问题?
谁知道?请帮我
加:
多亏了神秘主义者,我以同样的方式解决了这个问题。但是这个解决方案也可以。
for(int i = 0 ; i < (int)p.m_arg.size() ; ++i)
{
string& strr = p.m_arg[i]->getName();
const char* ccs = strr.c_str();
size_t ss = strlen(ccs);
}
因此,我认为 getName()的返回值是有效的,直到循环}关闭为止。
但有趣的是,下一个是不工作
for(int i = 0 ; i < (int)p.m_arg.size() ; ++i)
{
string* strr = &p.m_arg[i]->getName();
const char* ccs = strr->c_str();
size_t ss = strlen(ccs);
}
css是“悬挂”的,strr是“”
我头昏眼花,困惑!
最佳答案
在getName()
函数中:
string getName()
{
return name;
}
返回的字符串是原始字符串的副本。它成为以下表达式的中间体:
const char* ccs = p.m_arg[i]->getName().c_str();
表达式结束时,该中间体将被销毁。因此,使
c_str()
返回的指针无效。 结果是ccs
变成了悬空指针。 起作用的原因:
string str("ok");
const char* ckk = str.c_str();
是因为
str
不是中间体。要使其正常运行,请将您的循环更改为:
for(int i = 0 ; i < (int)p.m_arg.size() ; ++i)
{
string str = p.m_arg[i]->getName()
const char* ccs = str.c_str();
size_t ss = strlen(ccs);
}
编辑:要回答新问题:
这不起作用的原因:
string* strr = &p.m_arg[i]->getName();
和以前一样
getName()
返回一个中间体。然后,您将其地址分配给strr
。该语句之后销毁了中间体,因此strr
像第一种情况一样成为了悬空的指针。