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

时间:2017-02-05 08:00:50

标签: c++ string

这是一个功能:

void foo() {
   string str = "StackOverflo";
   str.push_back('w');
}

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

string foo() {
   string str = "StackOverflo";
   str.push_back('w');
   return str;
}

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

6 个答案:

答案 0 :(得分:25)

  

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

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

  

为什么?

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

答案 1 :(得分:17)

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

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

答案 2 :(得分:6)

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

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

foo函数返回str副本,因此您编码的内容正常。

答案 3 :(得分:5)

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

因此,您的str存储在Stack中,而其值存储在Heap中。 因为std::string使用char指针来分配您的"stackoverflow"

答案 4 :(得分:1)

在Windows平台上,在C ++中,使用std :: string,字符串大小小于14个字符左右(称为小字符串)存储在堆栈中,几乎没有开销,而上述字符串大小存储在具有开销的堆中。通常取决于平台和编译器,可以使用优化选项进行调整。

std :: string myStr {“ Hello World”}; //存储在程序堆栈中 std :: string myStr {“ StackOverflow拯救了程序员的生命”}; //指针存储在程序堆栈中,而内存存储在字符串中,并分配在堆中

下面的链接有很好的解释。 https://blogs.msmvps.com/gdicanio/2016/11/17/the-small-string-optimization/

答案 5 :(得分:0)

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

在堆上分配的最大也是唯一的理由是允许字符串对象增大大小,例如通过调用push_back()append()。存储在堆栈中的对象无法更改其大小-由C/C++语言定义。