Reputation: 51
i had met same situation in my project.
The following code were similarly reproduced.
#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);
}
}
the problem is //PROBLEM POINT
the return address of c_str() can't be assigned to const char* ccs.
in debugger, the css assigned memory address of return of c_str(), but css's value is "" and it work same as ""
but the next code is working as expected.
string str("ok");
const char* ckk = str.c_str();
after this code, ckk points after str.c_str() returnning addres, and ckk's value in debugger is "ok"
the same problem is occuring in std::wstring, wchar_t, unicode.
why did this problem occur?
who knows? help me plz~
ADD:
thanks to mystical i solve the problem same way. but this solution also work OK.
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);
}
so i think the return value of getName() is live until the loop } closed.
but interestingly, the next is don't work
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);
}
the css is 'dangling' and also strr is ""
i've dazed and confused!
Upvotes: 1
Views: 1374
Reputation: 471229
In your getName()
function:
string getName()
{
return name;
}
The string that is returned is a copy of the original. It becomes an intermediate in the following expression:
const char* ccs = p.m_arg[i]->getName().c_str();
When the expression ends, that intermediate is destroyed. Therefore invalidating the pointer returned by c_str()
. The result is that ccs
becomes a dangling pointer.
The reason why this works:
string str("ok");
const char* ckk = str.c_str();
is because str
is not an intermediate.
To make it work, change your loop to this:
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);
}
EDIT : To answer your new question:
The reason why this doesn't work:
string* strr = &p.m_arg[i]->getName();
is the same as before. getName()
returns an intermediate. You then take the address of this and assign it to strr
. The intermediate is destroyed after the statement, so strr
becomes a dangling pointer as in the first case.
Upvotes: 4