动态内存,堆栈内存和静态内存与c ++的区别?

时间:2012-07-23 03:23:59

标签: c++ memory

我想知道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

3 个答案:

答案 0 :(得分:1)

  

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

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

  1. p是一个数组,指向可修改的内存(已分配堆栈)。
  2. q是一个指针,指向已静态分配的只读内存。你真的应该把它声明为:

    const char * p =“whatever”;

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

答案 1 :(得分:1)

pq都是变量。 p的类型为“12 char的数组”,q的类型为“指向char的指针”。 pq都有自动存储时长。也就是说,它们被分配在堆栈中。

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中,这种不安全的转换已被删除。)

答案 2 :(得分: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.