为什么要用g ++优化它?至少,我认为这是正在发生的事情

nzc*_*nzc 4 c++

当我运行以下代码时

#include <iostream>
int main(int argc, char *argv []) {

  std::string simpleString("this is just a simple string");

  std::cout << "simpleString = " << simpleString << std::endl << std::endl;

  std::string one = (simpleString + ", one");

  const char * oneCharStar = one.c_str();
  std::cout << "simpleString + one: '" << oneCharStar << "'" << std::endl;

  const char * twoCharStar = (simpleString + ", two").c_str();
  std::cout << "simpleString + two: '" << twoCharStar << "'" << std::endl;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我的Fedora Core 23机器上,uname -a报告:

"Linux glorp 4.5.7-202.fc23.x86_64#1 SMP Tue Jun 28 18:22:51 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux"

和g ++ --version说

"g ++(GCC)5.3.1 20160406(Red Hat 5.3.1-6)"

第一个输出读取"这只是一个简单的字符串,一个",而第二个输出显示空字符串.

我想这里有一些优化,但是,在我之前的Ubuntu机器上(16.mumble,安静地休息),这段代码按照我的预期运行.我刚刚发现当我在新机器上重新编译我的应用程序(使用相同的make文件等)时,此代码如上所述失败.

此外,它也可以在以下平台上运行:

$ uname -a Linux t4240rdb

3.12.37-rt51 + g43cecda#2 SMP Fri Mar 4 18:18:03 EST 2016 ppc64 GNU/Linux

$ g ++ --version

g ++(GCC)4.9.2

版权所有(C)2014 Free Software Foundation,Inc.

这里发生了什么?谢谢!

Jus*_*tin 9

const char * twoCharStar = (simpleString + ", two").c_str();
Run Code Online (Sandbox Code Playgroud)

在此行之后,临时字符串将(simpleString + ", two")被销毁.

std::string分配内存,并c_str()返回指向该内存的指针.在std::string析构函数中,内存被释放.因此,在此行之后,twoCharStar指向已删除的内存.

释放后使用内存是未定义的行为.

  • 它在完整表达式*中有用*,但在*之后不是*.例如,`std :: cout <<(<makes-a-string>).c_str()<< std :: endl`是完全有效的,因为临时继续存活直到完整表达式结束. (5认同)
  • @nzc好消息是,一旦你学会了这些模式,它们就会在C++中应用.不得不考虑这样的事情是使C++比Java或Python等语言更难的部分原因.但能够做这样的事情是使C++变得强大的部分原因.抽象至少可以帮助你做到这一点,即使你必须注意这样的细节,也要少考虑一些事情.有些人一直在尝试开发语言或库来解决这些问题,但这不是一件容易的事 (3认同)
  • @nzc可以说你已经通过使用c_str()打破了抽象.毕竟,整个代码块可以写成没有`char*`.如果所有这些`char*`都被`std :: string`取代,那么问题就不会发生. (3认同)
  • @DOUGLASO.MOEN`(someString +"some literal")`创建一个`std :: string`,因为`std :: string`有一个`operator +`取一个`const char*` (2认同)