将std::string的c_str()返回值赋值给自身是否符合C++标准安全要求?
#include <string> #include <cstdio> int main() { std::string strCool = "My cool string!"; const char *pszCool = strCool.c_str(); strCool = pszCool; printf( "Result: %s", strCool.c_str() ); }
结论
该行为在C++11及后续版本中拥有明确的标准安全保障,并非是测试编译器的独有实现。
标准依据
C++11及更高版本的标准对std::string的operator=(const char*)重载做出了强制要求:
- 入参必须指向以
\0结尾的合法C风格字符串 - 赋值操作的执行顺序为先完整复制入参指向的字符串内容,再修改自身内部状态、释放旧缓冲区
因此即便入参就是当前对象c_str()返回的自身内部缓冲区指针,甚至是偏移后的后缀指针(只要仍在原缓冲区范围内且指向\0结尾的字符串),也不会出现读取已释放内存的悬垂指针问题。
旧版本兼容性说明
C++03及更早的标准没有对该场景做明确强制约束,理论上存在先释放旧缓冲区再复制内容的实现可能,但当时的主流编译器标准库也普遍对自赋值场景做了兼容处理,不会触发问题。
关于c_str()有效期的补充
你之前了解的「c_str()返回值仅在调用同一std::string对象的非const成员函数前有效」是通用规则,但该赋值场景属于标准明确覆盖的例外:赋值运算符的实现保证读取源字符串内容的步骤,发生在旧缓冲区被释放/修改之前,因此不会触发未定义行为。
内容的提问来源于stack exchange,提问作者Daniel Jennings
相关产品推荐
相关产品推荐

