首页 > 解决方案 > 字符串错误还是编译器错误?

问题描述

我遇到了以下问题,其中调试中的输出似乎完全违背了代码所说的内容,除非我遗漏了什么,否则它似乎可能是编译器中的一个错误。

所以这是代码,它应该创建两个文件名字符串并删除其中一个文件。

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"

如您所见,尽管字符串是使用具有不同字符串文字的两个不同表达式来初始化的,但在初始化之后,它们最终会成为指向同一字符串的相同指针。

这是一些编译器优化脱轨还是什么?

标签: c++stringc++11

解决方案


auto *real = (base_dir + "/index.txt").c_str();
auto *bkp = (base_dir + "/index.txt.new").c_str();
remove(real);

real在函数调用中使用,remove()real指向内部缓冲区std::string已被销毁,因为它是临时的,尝试从中读取是未定义的行为,因此这里唯一的错误是您的代码。


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

auto real = (base_dir + "/index.txt");
auto bkp = (base_dir + "/index.txt.new");
remove(real.c_str());

推荐阅读