【问题标题】:Stack memory allocation and deallocation mechanism堆栈内存分配和释放机制
【发布时间】:2011-05-23 22:13:38
【问题描述】:

如果我将值作为参数传递给特定函数,那么该函数会在函数执行结束时释放该参数的内存吗?

如果我将指针或引用作为参数传递,如果函数释放指针参数的内存会发生什么?会影响函数外的变量吗?

【问题讨论】:

    标签: c++ stack memory-management


    【解决方案1】:

    在第一种情况下,内存将被“释放”(实际上堆栈指针会增加)。如果这不是 POD 类型的变量析构函数被调用,那么如果在堆中分配的内存将从堆中释放。

    在第二种情况下,指针引用的值不会被释放 - 只会释放指针的内存。

    【讨论】:

      【解决方案2】:

      对于第 1 点,它取决于参数的类型。通过例如按值的“字符串”将执行隐式复制,并且当变量(函数参数)超出范围时,复制使用的内存将被释放。对于您自己的类型,这不会自动发生 - 您需要正确设置构造和销毁。

      对于第二个 - 是的,使用指针解除分配将影响它所寻址的内存 - 在函数内部和外部。

      澄清第二点:

      void func(char *someMemory) {
        delete[] someMemory;
      }
      
      //...
      char *myArray = new char[100];
      func(myArray);
      

      ...将删除分配的内存 - 在调用 func 失败后使用 myArray

      【讨论】:

      • 总是有一个隐式的复制构造函数,即使是你自己的类型。如果您不需要特定的语义,它们将按照与“字符串”相同的方式自动管理。
      • @Roberto:我说的是分配内存的类型。我应该说'不会必然自动发生':)
      【解决方案3】:

      如果您在堆栈上传递一个值或指针,则保存该值所需的内存将分配在堆栈上...

      堆栈的工作方式可以继续“分配”更多内存,但必须以相反的顺序“释放”。

      所以:

      void f(int *ptr, int v)
      {
      // Do something
      }
      

      当您调用 f() 时,ptr 和 v 的值被“推送”到堆栈上,即神奇地创建了足够的内存来保存这些值。当函数返回时,堆栈会以另一种方式调整,从某种意义上说,它们是从堆栈中“弹出”的。

      这种推送和弹出对原始指针或值没有影响。所以:

      ptr++;
      

      不会影响调用函数持有的指针的值。

      如果您取消引用 *ptr,则您正在访问从函数外部可见的相同数据的指针。如果你释放()指针,这会影响从函数外部看到的内容。因此,当您传递一个指针时,指针指向的原始数据没有副本,但实际指针有一个副本。指针按值传递。

      【讨论】:

        猜你喜欢
        • 2016-07-25
        • 2011-07-25
        • 2014-10-03
        • 1970-01-01
        • 2013-02-28
        • 2021-11-18
        • 1970-01-01
        • 2019-05-17
        • 2011-10-09
        相关资源
        最近更新 更多