Confusing std::string::c_str() behavior in VS2010

社会主义新天地 提交于 2019-12-12 03:36:50

问题


I'm sure I've done something wrong, but for the life of me I can't figure out what! Please consider the following code:

cerr<<el.getText()<<endl;
cerr<<el.getText().c_str()<<endl;
cerr<<"---"<<endl;
const char *value = el.getText().c_str();
cerr<<"\""<<value<<"\""<<endl;
field.cdata = el.getText().c_str();
cerr<<"\""<<field.cdata<<"\""<<endl;

el is an XML element and getText returns a std::string. As expected, el.getText() and el.getText().c_str() print the same value. However, value is set to "" - that is, the empty string - when it assigned the result of c_str(). This code had been written to set field.cdata=value, and so was clearing it out. After changing it to the supposedly-identical expression value is set from, it works fine and the final line prints the expected value.

Since el is on the stack, I thought I might have been clobbering it - but even after value is set, the underlying value in el is still correct.

My next thought was that there was some weird compiler-specific issue with assigning things to const pointers, so I wrote the following:

std::string thing = "test";
std::cout << thing << std::endl;
std::cout << thing.c_str() << std::endl;
const char* value = thing.c_str();
std::cout << value << std::endl;

As expected, I get 'test' three times.

So now I have no clue what is going on. It would seem obvious that there is something strange going on in my program that's not happening in the sample, but I don't know what it is and I'm out of ideas about how to keep looking. Can somebody enlighten me, or at least point me in the right direction?


回答1:


I assume that el.getText() is returning a temporary string object. When that object is destroyed the pointer returned by c_str() is no longer valid (keep in mind that that are other ways the pointer returned by c_str() can be invalidated, too).

The temporary object will be destroyed at the end of the full expression it's created in (which is generally at the semi-colon in your example above).

You may be able to solve your problem with something like the following:

const char *value = strdup(el.getText().c_str());

which creates a copy of the string as a raw char array in dynamically allocated memory. You then become responsible for calling free() on that pointer at some point when that data is no longer needed.



来源:https://stackoverflow.com/questions/14533540/confusing-stdstringc-str-behavior-in-vs2010

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!