字符串的c_str()函数的C ++奇怪行为 [英] C++ strange behavior with string's c_str() function

查看:61
本文介绍了字符串的c_str()函数的C ++奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将项目从Visual Studio 06迁移到2010.这样做的时候,我在代码中观察到了这种现象.我有一个如下所示的Get string函数:

  string GetTheStr(){返回strSomeStdString;} 

然后在get函数上方调用另一个函数,如下所示:

  const char * ptrStr =(char *)GetTheStr().c_str(); 

ptrStr指向的字符串的值为"

以上代码在Visual Studio 06中工作正常,但在Visual Studio 2010中却无法正常工作.

然后我尝试了几次实验:

  std :: string str = GetTheStr();//->str内部的值正确显示const char * PtrCStr = str.c_str();//->PtrCStr指向的值正确显示const char * PtrData = str.data();//->由PtrData指向的值正确显示const char * ptr =(char *)GetTheStr().c_str();//->ptr指向的值未正确显示 

我想知道为什么最后一行不起作用.谁能告诉我为什么上述行为会在Visual Studio 2010中发生而在Visual Studio 06中却没有发生?

先谢谢您了:)

解决方案

在无效情况下发生的事情是GetTheStr()返回一个临时值,然后c_str()返回对其内部数据的引用,然后该临时值超出范围,突然之间您就失去了对存储的不再有效的引用.当您将GetTheStr()的返回值分配给命名变量时,该变量仍然有效,并且其c_str()的结果仍指向有效数据.

临时对象的生存期在不同的实现之间有所不同.据我了解,整个语句的临时生命( std :: cout<< GetTheStr().c_str()<<< 在技术上对我的理解是有效的,因为lifteime必须持续到整个语句,但写得不好,因为它依赖于生命周期的一个非常细微的方面);但是,据我所知,临时对象的生存期是否超出该声明的持续时间,取决于我的理解.对于最后一段,我可能会受到嘲笑(特别是对这一主题有更精通知识的人),但是简短的故事是,当需要延长对象的生存期时,写得好的代码应该更加明确.如果需要保留对对象内部数据的引用,那么始终最好保证有一个引用对象的命名变量,以确保包含对象的生存期超过其内部数据使用的生存期./p>

I am moving my project from Visual Studio 06 to 2010. While doing so, I have observed this behavior in my code. I have a Get string function that look like this:

string GetTheStr() 
{ 
        return strSomeStdString; 
} 

Then there is another function that call above get function like this:

const char* ptrStr = (char *)GetTheStr().c_str();

the value of string pointed by ptrStr is ""

above code was working fine in visual studio 06 but not on visual studio 2010.

Then I tried few experiments:

std::string str = GetTheStr(); // -> value inside str displayed correctly
const char* PtrCStr = str.c_str(); // -> value pointed by PtrCStr displayed correctly
const char* PtrData = str.data(); // -> value pointed by PtrData displayed correctly
const char* ptr = (char *)GetTheStr().c_str(); // -> value pointed by ptr NOT displayed correctly

I am wondering why last line didn't work. Can anyone please tell me why above behavior happen in visual studio 2010 but not on visual studio 06?

Thanks in advance :)

解决方案

What's happening in the invalid case is that GetTheStr() is returning a temporary, then c_str() is returning a reference to its internal data, then the temporary goes out of scope and suddenly you have a dangling reference to storage that is no longer valid. When you assign the returned value of GetTheStr() to a named variable, the variable is still alive and the result of its c_str() is still pointing to valid data.

Lifetimes of temporaries is something that varies between implementations. It is my understanding that a temporary lives for the entire statement (std::cout << GetTheStr().c_str() << endl; is technically valid to my understanding because the lifteime is required to last for the entire statement, but poorly written because it is relying on a very subtle aspect of lifetime); however, whether a temporary lives beyond that statement to the end of the scope or not is, to my understanding, implementation-defined. I'm probably going to be pilloried for this last paragraph (especially by people with more precise knowledge on the topic), but the short story is that well written code should be more explicit when the lifetime of an object needs to be extended; if you need to retain a reference to the internal data of an object, then it's always best to guarantee that there is a named variable referring to the object to ensure that the containing object's lifetime exceeds the lifetime of the usage of its internal data.

这篇关于字符串的c_str()函数的C ++奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆