我想知道C++中动态内存、栈内存和静态内存的区别。
以下是一些代码作为示例:
#include<iostream>
using namespace std;
char *GetMemory(void)
{
char p[]="hello world";
char *q="hello world";
return q;
}
int main(void)
{
return 0;
}
为什么是 p
在栈内存中,而q
在动态内存中呢?
为什么堆栈内存中的“p”是动态内存中的“q”?
这不是真的; 两者p
都q
分配有自动存储持续时间(实现为堆栈结构)。它们之间的区别是:
p
是一个数组并指向可修改的内存(分配的堆栈)。q
是一个指针,指向静态分配的只读内存。您确实应该将其声明为:
const char *p = "随便";
这里没有动态分配。您没有调用new
,malloc
或一些使用幕后分配内存的例程。因此,p
从该函数返回是不正确的,因为一旦函数返回,它将无效。
p
并且q
都是变量。 p
类型为“12 的数组char
” q
,类型为“指向的指针char
”。两者都p
具有q
自动存储期限。也就是说,它们被分配在堆栈上。
q
是一个指针,它被初始化为指向字符串的初始字符"hello world"
。此字符串是字符串文字,所有字符串文字都有静态存储持续时间。
p
是一个数组,所以当你p
用一个字符串字面量进行初始化时,它会导致p
声明一个字符数组,而当它被初始化时,字符串字面量的内容会被复制到数组中。因此,当GetMemory()
被调用时,会在堆栈上为数组分配空间p
,并将字符串文字的内容"hello world"
复制到该数组中。
您的代码不会执行动态分配。
请注意,因为q
是指向具有静态存储持续时间的字符数组的指针,所以q
从函数返回是安全的:它指向的数组将在程序的整个持续时间内存在。但是,返回是不安全的p
,因为p
函数返回时不再存在。
另请注意, 的类型"hello world"
是char const[12]
。C++ 中有一个不安全的隐式转换,它允许将字符串文字转换为char*
指向字符串文字的初始字符的指针。这是不安全的,因为它默默地放弃了 const 限定。处理字符串文字时应始终使用const char*
,因为字符不可修改。(在 C++ 语言的最新版本 C++11 中,这种不安全的转换已被删除。)
对于您的示例,由于您使用的是字符串文字,因此很可能将其写入可执行文件的 DATA 段。没有分配动态内存。一个更好的例子是这样的:
void foo()
{
//This is a stack variable. Space is allocated
//on the stack to store it. Its lifetime is
//the routine that calls it.
some_class stack_variable;
//This is a heap-allocated variable. It will
//remain in memory indefinitely unless deleted.
//If a pointer to this isn't returned, and it
//isn't deleted by the end of the routine, this
//will become a "memory leak".
another_class *heap_variable = new another_class();
//This is a (method) static variable. It retains its
//value between method calls
static int method_static = 1;
++method_static;
}
在右大括号处,stack_variable 被清理(即它占用的堆栈空间被回收)。heap_variable 没有被删除,因此是内存泄漏。如果我们多次调用这个方法:
for(int i = 0; i < 5; ++i) { foo(); }
然后 method_static 的值为 5。