C++ 字符串错误还是编译器错误?

C++ 字符串错误还是编译器错误?,c++,string,c++11,C++,String,C++11,我遇到了以下问题,debug中的输出似乎完全违背了代码所说的内容,并且它可能是编译器中的一个bug,除非我遗漏了什么 下面是代码,它应该创建两个文件名字符串并删除其中一个文件 auto *real = (base_dir + "/index.txt").c_str(); auto *bkp = (base_dir + "/index.txt.new").c_str(); remove(real); 然而,它在实践中并没有表现出这种行为,事实上,我们在gdb中得到了以下结果: auto *rea

我遇到了以下问题,debug中的输出似乎完全违背了代码所说的内容,并且它可能是编译器中的一个bug,除非我遗漏了什么

下面是代码,它应该创建两个文件名字符串并删除其中一个文件

auto *real = (base_dir + "/index.txt").c_str();
auto *bkp = (base_dir + "/index.txt.new").c_str();
remove(real);
然而,它在实践中并没有表现出这种行为,事实上,我们在gdb中得到了以下结果:

auto *real = (base_dir + "/index.txt").c_str();
(gdb) n
auto *bkp = (base_dir + "/index.txt.new").c_str();
(gdb) n
remove(real);
(gdb) p real
$1 = 0x7060e8 "./ss-clientdir/index.txt.new"
(gdb) p bkp
$2 = 0x7060e8 "./ss-clientdir/index.txt.new"
因此,正如您所看到的,尽管字符串是使用两个具有不同字符串文本的不同表达式初始化的,但在初始化之后,它们最终成为指向同一字符串的同一指针

这是编译器优化出了轨道还是什么

auto *real = (base_dir + "/index.txt").c_str();
auto *bkp = (base_dir + "/index.txt.new").c_str();
remove(real);
在函数调用
remove()
中使用
real
,但是
real
指向
std::string
中的一个内部缓冲区,该缓冲区已被销毁,因为它是临时的,尝试从中读取是未定义的行为,因此这里唯一的错误是代码


若要解决此问题,请保存字符串,然后请求一个
c_str()


记住编程的第一条规则:欢迎来到C++。在你陷入困惑之前,这里有一些方便的阅读:这是一些编译器优化出了轨道还是什么——除了@Yksisarvinen的评论之外,你应该意识到你正在使用的编译器被成千上万的人使用,如果不是世界上成千上万的公司,也可能是几百家。如果在你演示过的一个小的玩具程序中有这样的编译器错误,那么大多数C++社区都会谈论它并通知编译器编写者(并且会让维护编译器的人感到尴尬)。因此,这不太可能是一个编译器错误。在适当的语言中,这将是一个错误。在C++中,这是“你的错”。“波恩,我们不要谈论java和适当的语言。”
auto real = (base_dir + "/index.txt");
auto bkp = (base_dir + "/index.txt.new");
remove(real.c_str());