2011-10-31 124 views
1

我在我的项目中遇到过同样的情况。
下面的代码被类似地转载。
visual studio 2008 sp1 std :: string :: c_str()err

#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); 
} 

} 

问题//问题POINT
c_str的返回地址()不能分配给为const char * CCS
调试器,c_str()的回报CSS分配的内存地址,但CSS的值是‘’,它的工作一样‘’

但接下来的代码工作作为预期。

string str("ok"); 
const char* ckk = str.c_str(); 

这个代码后,CKK后str.c_str() returnning ADDRES,和CKK的调试器的值是 “OK”

同样的问题是发生在std :: wstring,wchar_t,unicode。

为什么会出现此问题?
谁知道?帮我PLZ〜

地址: 感谢神秘我解决问题的方法相同。但是这个解决方案也可以。

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“”
我茫然和困惑!

回答

4

在你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与第一种情况一样成为悬挂指针。

+1

另一个解决方法是让'getName()'返回一个'std :: string const&'(函数本身也应该是'const')。然后表达式是有效的,并且没有涉及的字符串的复制。 – Mat

+0

你也可以更进一步,将它嵌入到'strlen'中。但是循环显然是不完整的,因为'ss'从不使用。 – Mysticial

+0

'strlen'也很可疑; 'std :: string :: size()'是O(1)而不是O(n)。 – MSalters

相关问题