强制转换 c_str() 仅适用于短字符串

2024-02-16

我正在 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(使用前将#替换为@)

强制转换 c_str() 仅适用于短字符串 的相关文章

随机推荐