在内存中分配的std :: string在哪里?

And*_*oiu 24 c++ string

这是一个功能:

void foo() {
   string str = "StackOverflo";
   str.push_back('w');
}
Run Code Online (Sandbox Code Playgroud)

当我们在函数内部声明字符串时,它是存储在堆栈还是堆中?为什么?

string foo() {
   string str = "StackOverflo";
   str.push_back('w');
   return str;
}
Run Code Online (Sandbox Code Playgroud)

我们可以返回字符串引用并继续使用程序中的其他位置吗?

R S*_*ahu 29

当我们在函数内声明String时,它是存储在Stack还是Heap?

字符串对象本身存储在堆栈中,但它指向堆上的内存.

为什么?

定义语言使得字符串对象存储在堆栈中.string的构造对象的实现使用堆上的内存.

  • 当我们从函数返回字符串时会发生什么?它会发送该字符串的副本并且该字符串会从内存中消失吗?或者它会返回一个指向该内存的指针,然后它就会消失? (2认同)
  • @AndreiMargeloiu它将返回std :: string的副本,只要你将它存储在某个地方就可以使用.你不必担心它的内部数据std :: string完美地处理它自己的数据字符指针 (2认同)

Wag*_*ota 19

对象str(它是类的实例std::string)在堆栈中分配.但是,字符串数据本身可以在堆中分配.这意味着该对象具有指向包含实际字符串的缓冲区的内部指针.但是,如果字符串很小(如本例所示),通常字符串类将具有我们称之为"小字符串优化"的字符串.这意味着std::string对象本身的大小足以包含字符串的数据,如果它足够小(通常约23个字节+ 1个字节的空终止符)...然后如果内容大于此,则字符串数据将在堆中分配.

通常你可以正常返回你的字符串.C++可以为您处理这个问题.移动语义可以处理此处所需的任何内容,以返回指向原始字符串的相同字符串数据的字符串对象,从而避免执行不必要的副本.

  • 因为堆栈比堆小得多,这会导致“堆栈溢出” (3认同)
  • 除了移动之外,还有返回值优化:https://en.wikipedia.org/wiki/Copy_elision#Return_value_optimization 这种方式甚至不需要移动,字符串可能被构造成返回值。 (2认同)

sel*_*bie 6

"StackOverflo"字符串文字可能存储在二进制文件的只读数据空间中,并在程序启动时映射到内存中.你可以在这里阅读更多相关信息.

str,类实例`,在堆栈上分配.但是它的构造函数分配给内存字符串文字的副本的内存是在堆上分配的.

foo函数返回一个复制str,所以你有什么编码就可以了.

  • _但是它的构造函数分配的内存是为了在堆上分配字符串文字的副本.除非字符串足够小.然后小的字符串优化可能会启动. (4认同)

Lor*_*dez 5

C++中的所有局部变量都是Stack中的存储.甚至本地指针也存储在Stack中.但指针中分配的内存存储在Heap中.

因此,您str的存储在堆栈中,而其值存储在堆中.因为std::string使用char指针来分配你的"stackoverflow"

  • 实际上,它可能比那更复杂.许多C++实现都有所谓的小字符串优化.对于一些小字符串,它们的内容位于`string`实例内(不在堆上).细节是特定于实现的. (2认同)