这是一个功能:
void foo() {
string str = "StackOverflo";
str.push_back('w');
}
当我们在函数内部声明字符串时,它是存储在堆栈还是堆中?为什么呢?
string foo() {
string str = "StackOverflo";
str.push_back('w');
return str;
}
我们可以返回字符串引用并继续使用程序中的其他位置吗?
答案 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++
语言定义。