字符串错误或编译器错误

String Bug or Compiler Bug?

本文关键字:错误 编译器 字符串      更新时间:2023-10-16

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

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

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

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