【发布时间】:2021-10-12 08:48:53
【问题描述】:
关于std::string,以下代码是否被标准保证安全?
#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_str 的结果只能保证安全使用,直到对同一 std::string 进行另一个方法调用,但我不清楚传递 const char * 是否安全是否返回分配方法。
使用实际编译器(最新版本的 GCC、Clang 和 MSVC)进行测试时,它们似乎都支持这种行为。
此外,编译器还支持将字符串的后缀分配回自身,例如strCool = pszCool + 3 在这个例子中;结果将是该字符串与传入的字符串具有相同的值。
这种行为是否以某种方式得到保证,或者我只是幸运的是我测试过的编译器提供的标准库支持这种情况?
【问题讨论】:
-
嗨!你标记了这个问题
stl,但看起来你正在使用 C++ 标准库。你用的是哪个库?另请参阅 What's the difference between "STL" and "C++ Standard Library"? 和stl说明。 -
听起来你没有“测试”过任何东西。您只是保存了指向 C 字符串的指针,并验证没有发生崩溃。看here:
The c_str() result becomes invalid if the std::string is destroyed or if a non-const member function of the string is called. So, usually you will want to make a copy of it if you need to keep it around.换句话说,a) 确保原始 std::string 保持不变,和/或 b) strcpy() 到另一个缓冲区。 -
抛开标准中的任何一点点:我希望典型的 C++ 库实现要么在删除旧缓冲区之前分配一个新的内部缓冲区,要么在新字符串适合的情况下重用相同的缓冲区。如果 C++ 标准要求任何一种行为,我会感到惊讶,因此默认情况下,这变得未指定。如果实现选择重用缓冲区,这将成为重叠副本,这是未定义的行为。这就是我的理由。
-
@paulsm4 我通过在调试器中单步执行代码并识别例如如上所述的 memmove 操作,这并不能很好地转化为 StackOverflow 问题,尽管我本可以承认这一点。
-
@Brian 谢谢,我的意思是用 STD 来标记它,这已经有用地修复了 :)
标签: c++ language-lawyer std