堆与栈的区别是啥?
内存中的堆栈段区是啥意思?

解决方案 »

  1.   


    高质量C++编程指南:内存分配方式有三种:
    (1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
    (2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
    (3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
      

  2.   

    我们都知道,当我们想得到一块特定大小的存储区域的时候,可以用声明变量来获取,也可以用new操作符获取。例如我想获得一块存储4个整数的空间,以下方式都可以得到:
    int iArray[4];
    int pPointer = new int[4];
    这两种方式是不相同的。声明变量/数组的方式,是在栈中分配内存。程序中的每一个函数都有自己的栈,用于为函数作用域内的变量/对象分配存储空间。当调用完此函数返回的时候,栈空间自动被收回,其中的内容也就全部无效了。而new是在堆中分配内存的,而且一经分配则永久保留,直到显式的以delete运算符来释放掉。如果不进行delete,则会造成内存泄露。
    C函数库中的malloc/free也是在堆中分配内存的,与new/delete相比,二者在为对象分配空间的时候有所区别。关于这个此处不做过多解释,有兴趣的读者可以去查阅相关资料。
    下面举一个例子,来演示堆内存和栈内存的使用。
    char *GetMemory(void)
    {
    char p [] ="Hello world";
    return p;
    }
    void Test(void)
    {
    char *str =NULL;
    str =GetMemory();
    printf(str)}
    {
    建立一个完整的程序,调用以上的Test函数,然后看看输出了什么?Hello world哈哈……成功!~~~~~~~~~~~~~~~
    再运行一遍,乱码!!!
    再来一遍?一半正确,一般是乱码!!!
    有鬼呀~~~~~~~~~~~~~~呵呵……是栈内存在作怪。
    char p [] =="Hello world";是在栈中分配的存储区域,它在GetMemory返回时已经失效了,里面的内容可能任何值但是已经没有了意义。
    将以上程序改动一下:
    char *GetMemory(void)
    {
    char str[] = "Hello world";
    int isize = strlen(str) + 1;
    char *p = new char[isize];
    memcpy(p, str, isize);
    return p;
    }
    编译,运行……
    Hello world
    再来一遍?来十遍都不会错了!这里返回的是指向堆内存的指针,即使函数结束了也不会释放。当然,如果你在程序结束前不用delete释放掉它的话,它就永远在哪儿了 。这也应该叫做“常驻内存”吧?哈哈……