在VS2010中混淆std :: string :: c_str()行为

Rob*_*ert 0 c++ stl const stdstring visual-studio-2010

我确定我做错了什么,但对于我的生活,我无法弄清楚是什么!请考虑以下代码:

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;
Run Code Online (Sandbox Code Playgroud)

el是一个XML元素并getText返回一个std :: string.正如预期的那样,el.getText()el.getText().c_str()打印相同的值.但是,当它分配结果时,value设置为""- 即空字符串c_str().此代码已写入设置field.cdata=value,因此清除它.将其更改为所谓的相同表达式value后,它可以正常工作,最后一行打印出预期值.

因为el在堆栈中,我认为我可能已经破坏了它 - 但即使在value设置之后,基础值el仍然是正确的.

我的下一个想法是,有一些奇怪的编译器特定问题,将事物分配给const指针,所以我写了以下内容:

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;
Run Code Online (Sandbox Code Playgroud)

正如所料,我进行了三次"测试".

所以现在我不知道发生了什么.很明显,我的程序中有一些奇怪的事情在样本中没有发生,但我不知道它是什么,我不知道如何继续寻找.有人可以启发我,或者至少指出我正确的方向吗?

Mic*_*urr 5

我假设el.getText()是返回一个临时string对象.当该对象被销毁时,返回的指针c_str()不再有效(请记住,返回的指针的其他方式c_str()也可以无效).

临时对象将在其创建的完整表达式的末尾被销毁(在上面的示例中通常位于分号).

您可以使用以下内容解决问题:

const char *value = strdup(el.getText().c_str());
Run Code Online (Sandbox Code Playgroud)

char在动态分配的内存中创建字符串的副本作为原始数组.然后free(),当不再需要该数据时,您将负责在某个时刻调用该指针.

  • @Robert,`getText`返回的字符串是`e1`中字符串的临时*副本*.由于源是临时的,当临时变为无效时,指针变为无效 - 在第一个分号处. (2认同)
  • @Robert不是'el`超出范围,而是`getText()`函数返回的`std :: string`.返回值超出赋值语句末尾的范围,您将其赋值给`value`.此后`value`指向一个解除分配的对象,访问它是未定义的行为. (2认同)