将字符串文字分配给std :: string

nan*_*lee 11 c++ string const

我知道以下代码将创建一个字符数组并保留在内存中,直到程序结束:

char* str = "this is a string";
Run Code Online (Sandbox Code Playgroud)

至于这个语句,创建一个本地字符数组,当str超出范围时将被释放:

char str[] = "this is a string";
Run Code Online (Sandbox Code Playgroud)

我很好奇的是,当我这样写时会发生什么:

std::string str = "this is a string";
Run Code Online (Sandbox Code Playgroud)

str应该在它自己的内存(本地)中创建一个字符串的副本,但字符串文字本身呢?它是否具有程序的生命周期,或者当str超出范围时是否会被释放?

das*_*ght 7

当你写这个

std::string str = "this is a string";
Run Code Online (Sandbox Code Playgroud)

C++应该找一个构造函数std::string是需要const char*,要求它做一个临时对象,调用拷贝构造函数来复制临时进入str,然后销毁临时对象.

但是,有一个优化允许C++编译器跳过临时对象的构造和销毁,因此结果与之相同

std::string str("this is a string");
Run Code Online (Sandbox Code Playgroud)

但字符串文字本身呢?它是否具有程序的生命周期,或者当str超出范围时是否会被释放?

当您以这种方式使用时,字符串文字本身无法被您的程序访问.通常,C++将它放在与其他字符串文字相同的段中,使用它传递给构造函数std::string,并忘记它.允许优化器消除所有字符串文字中的重复项,包括仅在其他对象的初始化中使用的字符串文字.

  • IIRC,这里可以调用`operator =`,因为这需要两侧构造的对象.相反,用`=`初始化调用复制构造函数. (7认同)

Dav*_*aim 5

大多数操作系统会将程序存储器分为几部分

  • 堆栈
  • 数据段
  • BSS细分市场
  • 代码段

您已经知道堆栈和堆,但是其他的呢?

代码段将所有操作保持为二进制形式。

现在变得有趣了:让我们看下面的代码:

int x;
class Y{  static int y;  };
int main(){
  printf("hello world");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在哪里呢程序分配xy?它们不是本地的,也不是动态分配的,那么在哪里呢?

数据段保留所有静态和全局变量,在加载程序时,该段保留足够的字节以容纳所有静态和全局变量。如果变量是对象,则在程序启动时它将为所有变量(包括对象)分配足够的字节。在main程序调用每个全局对象构造函数之前,以及在main完成之后,它以相反的顺序调用每个对象析构函数,即称为构造函数。

BSS段是Data段的子集,它保留以null插入的全局和静态指针。

因此,假设未对字符串文字进行优化,则程序会将其存储在数据段中。只要程序有效,它将一直存在。此外,如果它是字符串文字,则很可能甚至可以在exe中看到它!将exe作为文本文件打开。在此过程中,您会清楚地看到字符串。

现在呢 std::string str = "hello world";

这是一个时髦的情况。str本身就生活在堆栈中。实际的内部缓冲区位于堆中,但是用于分配字符串的字符串文字位于数据段中,而使str价值转化为hello world代码的代码位于代码段中。不用说,如果要进行汇编编程,我们将需要用自己的双手建立这个生态系统。