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

时间:2019-02-18 21:21:00

标签: c++ string c++11

我遇到了以下问题,调试中的输出似乎完全违背了代码中所说的内容,除非缺少某些内容,否则似乎是编译器中的错误。

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

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"

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

这是一些编译器优化脱离轨道了吗?

1 个答案:

答案 0 :(得分:10)

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());