我正在 C++ 中使用 C 库并编写了一个包装器。有一次我需要转换一个std::string
到一个c风格的字符串。有一个带有函数的类,它返回一个字符串。如果字符串很短,则转换返回的字符串有效,否则无效。这是一个简单的简化示例来说明该问题:
#include <iostream>
#include <string>
class StringBox {
public:
std::string getString() const { return text_; }
StringBox(std::string text) : text_(text){};
private:
std::string text_;
};
int main(int argc, char **argv) {
const unsigned char *castString = NULL;
std::string someString = "I am a loooooooooooooooooong string"; // Won't work
// std::string someString = "hello"; // This one works
StringBox box(someString);
castString = (const unsigned char *)box.getString().c_str();
std::cout << "castString: " << castString << std::endl;
return 0;
}
执行上面的文件会将其打印到控制台:
强制转换字符串:
而如果我交换评论someString
,它正确打印
演员字符串:你好
这怎么可能?
你正在调用c_str
在由返回的临时字符串对象上getString()
成员函数。返回的指针c_str()
仅当原始字符串对象存在时才有效,因此在您分配的行的末尾castString
它最终成为一个悬空指针。正式地,这会导致未定义的行为。
那么为什么这对短字符串有效呢?我怀疑您正在看到短字符串优化的效果,这是一种优化,对于小于特定长度的字符串,字符数据存储在字符串对象本身的字节内而不是堆中。返回的临时字符串可能存储在堆栈中,因此当它被清理时,不会发生释放,并且指向过期字符串对象的指针仍然保存旧的字符串字节。这似乎与您所看到的一致,但这仍然并不意味着您正在做的事情是个好主意。 :-)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)