1

我想知道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在动态内存中呢?

4

3 回答 3

1

为什么堆栈内存中的“p”是动态内存中的“q”?

这不是真的; 两者pq分配有自动存储持续时间(实现为堆栈结构)。它们之间的区别是:

  1. p是一个数组并指向可修改的内存(分配的堆栈)。
  2. q是一个指针,指向静态分配的只读内存。您确实应该将其声明为:

    const char *p = "随便";

这里没有动态分配。您没有调用new,malloc或一些使用幕后分配内存的例程。因此,p从该函数返回是不正确的,因为一旦函数返回,它将无效。

于 2012-07-23T03:28:11.477 回答
1

p并且q都是变量。 p类型为“12 的数组charq,类型为“指向的指针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 中,这种不安全的转换已被删除。)

于 2012-07-23T03:28:30.717 回答
0

对于您的示例,由于您使用的是字符串文字,因此很可能将其写入可执行文件的 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。

于 2012-07-23T03:35:22.400 回答