强制转换c_str()仅适用于短字符串 [英] Casting c_str() only works for short strings

查看:147
本文介绍了强制转换c_str()仅适用于短字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C ++中使用一个C库,并编写了一个包装器.某一时刻,我需要将std::string转换为c样式的字符串.有一个带有函数的类,该函数返回一个字符串.如果字符串较短,则强制转换返回的字符串,否则无效.这是一个简单而精简的示例,说明了这个问题:

I'm using a C library in C++ and wrote a wrapper. At one point I need to convert an std::string to a c-style string. There is a class with a function, which returns a string. Casting the returned string works if the string is short, otherwise not. Here is a simple and reduced example illustrating the issue:

#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;
}

执行上面的文件会将其打印到控制台:

Executing the file above prints this to the console:

castString:

castString:

如果我在someString上交换评论,它将正确打印

whereas if I swap the commenting on someString, it correctly prints

castString:您好

castString: hello

这怎么可能?

推荐答案

您正在对getString()成员函数重新调整的临时字符串对象调用c_str. c_str()返回的指针仅在原始字符串对象存在的情况下才有效,因此在分配castString的行的末尾,它最终成为悬空指针.正式地,这会导致不确定的行为.

You are invoking c_str on a temporary string object retuned by the getString() member function. The pointer returned by c_str() is only valid as long as the original string object exists, so at the end of the line where you assign castString it ends up being a dangling pointer. Officially, this leads to undefined behavior.

那么为什么这对于短字符串有效?我怀疑您正在看到短字符串优化的效果,该优化针对小于特定长度的字符串,字符数据存储在字符串对象本身的字节中,而不是存储在堆中.返回的临时字符串可能存储在堆栈中,因此在清理临时字符串时不会发生任何释放,并且指向过期字符串对象的指针仍然保留您的旧字符串字节.这似乎与您所看到的相符,但这仍然并不意味着您正在做的事是个好主意. :-)

So why does this work for short strings? I suspect that you're seeing the effects of the Short String Optimization, an optimization where for strings less than a certain length the character data is stored inside the bytes of the string object itself rather than in the heap. It's possible that the temporary string that was returned was stored on the stack, so when it was cleaned up no deallocations occurred and the pointer to the expired string object still holds your old string bytes. This seems consistent with what you're seeing, but it still doesn't mean what you're doing is a good idea. :-)

这篇关于强制转换c_str()仅适用于短字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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