最近正好在查阅这方面的资料,看到网络上一些文章对于QString转 char* 和 const char* 的方法是这样说明的:
QString str(“hello world!”);
转成const char * :
const char * arr = str.toStdString.c_str();
转成 char * :
char * arr = str.toStdString.data();
然而, 首先不谈toStdString没有加括号,正确的是toStdString()。这个代码本身就存在一些问题:
const char* 和 char* 并不直接存储字符串中的字符,它们本身而是指针,指向的是一块内存空间,内存空间内才有字符串中的字符。在QString执行toStdString()函数后,返回的是std::string,而无论是c_str()还是data(),都是返回指向这个std::string中存储字符的存储空间的指针,所以首先要有这个string的存在,然后这些函数返回的结果才会准确。
但是众所周知,函数结束后返回值在被一个变量(之类的)接收后即被销毁。因此即使在执行c_str()和data()时还未被销毁,在std::string的存储空间的指针被赋值给arr时,std::string就已经被销毁了,所以最终arr指针指向的内存空间的值也只能是空或者乱码。(可能描述有些不准确,望指正)Visual Studio 对这个错误的解释是:
image.png所以这种方法并不能长久在arr中存储转来的字符。
而下列代码则是正确的:
std::string stdstr = str.toStdString();
因为对于std::string的等号是对实例的拷贝,而不像指针,虽然指针中的等号是拷贝地址,但是地址内的值并未拷贝新的一份,新的指针仍然指向的是原本的内存空间。
解决方法根据具体情况有所不同。
根据上面的描述可以得到:最简单的方法是将std::string持久化,比如下述:
std::string stdstr = str.toStdString();
char* arr = stdstr.data();
const char* arr = stdstr.c_str();
但是如果stdstr也只是一个函数中的变量,而arr需要传递至函数外,因为函数执行完毕后里面的变量也会被销毁,此时需要采用其他的方法,比如在更大范围将std::string持久化,等等,具体情况请自行研究。
如果文章有描述不当或错误请在评论区讨论、指正,一些问题也可以在评论区讨论、交流。
如果这篇文章大家觉得有意义的话请多多点赞、收藏支持,也可以在下面点击“赞赏支持”按钮打赏支持我哟~
网友评论