先来看段代码
#include <iostream>
#include <string>
std::string myBlog()
{
return "https://blog.csdn.net/caoshangpa";
}
int main()
{
const char *p = myBlog().c_str();
std::cout << p << std::endl;
return 0;
}
预期输出:https://blog.csdn.net/caoshangpa,但实际上无论是VC++还是g++编译器下,输出都是乱码。
但是把字符串改短点,比如改成“CSDN”,VC++编译器下输出为空,但在g++编译器下,是能正常输出的。
因此这个问题非常隐蔽,不仅与编译器相关,还和临时变量的具体内容相关,一旦发生,很难定位。
myBlog()是一个零时变量,等价于std::string("https://blog.csdn.net/caoshangpa")。这行语句结束时这个变量就被析构了,指针c_str()指向的内存也被回收,所以下面使用的c_str()指向的内存已经被释放了,所以无法输出我的博客网址。
改成下面这样能正常输出:
#include <iostream>
#include <string>
std::string myBlog()
{
return "https://blog.csdn.net/caoshangpa";
}
int main()
{
std::string str = myBlog();
const char *p = str.c_str();
std::cout << p << std::endl;
// 或
std::cout << myBlog().c_str() << std::endl;
return 0;
}
那么临时变量是何时析构的呢?再来看段代码
#include <iostream>
#include <string>
class MyClass
{
public:
MyClass()
{
std::cout << "MyClass constructor" << std::endl;
}
~MyClass()
{
std::cout << "MyClass destructor" << std::endl;
}
};
int main()
{
MyClass(); // 临时对象
std::cout << "https://blog.csdn.net/caoshangpa" << std::endl;
return 0;
}
输出结果如下:
并非是:
MyClass constructor
https://blog.csdn.net/caoshangpa
MyClass destructor
这说明在执行完MyClass(); 后,临时对象就析构了。
稍作修改:
#include <iostream>
#include <string>
class MyClass
{
public:
MyClass()
{
std::cout << "MyClass constructor" << std::endl;
}
~MyClass()
{
std::cout << "MyClass destructor" << std::endl;
}
};
int main()
{
MyClass(),// 如果这里是逗号
std::cout << "https://blog.csdn.net/caoshangpa" << std::endl;
std::cout << "CSDN Cao Shang Pa" << std::endl;
return 0;
}
输出结果如下:
由此可见, 临时对象是在遇到其后的第一个分号(语句结束处)析构的。
在Qt中经常会存在QString转char *的情况
QString str("Hello World!");
const char * arr = str.toStdString().c_str();
char * arr = str.toStdString().data();
const char * arr = str.toUtf8().constData();
char * arr = str.toUtf8().data();
............
根据上面的分析,这些都是存在问题的
参考链接:https://blog.csdn.net/stpeace/article/details/46461167