memory-management - C++ stack heap memory allocation - 栈和堆是什么,在哪里?

Garbage collection C++ / memory-management / stack / language-agnostic / heap / dynamic-memory-allocation

编程语言书籍解释了值类型是在堆栈上创建的,而引用类型是在堆上创建的,而没有解释这两种东西是什么。我还没有阅读清楚的解释。我了解堆栈是什么。但,

RajeshKdev



Answer #1

我将提供一些简单的注释C代码来说明这一切。最好的学习方法是在调试器下运行一个程序,观察其行为。如果你喜欢读python,请跳到答案的最后:)

//首次加载程序/ DLL时在数据段中静态分配
//当程序/ DLL退出时释放
//范围-可以从代码中的任何位置访问
int someGlobalVariable;

//首次加载程序时在数据段中静态分配
//当程序/ DLL退出时释放
//范围-可以从此特定代码文件中的任何位置访问
static int someStaticVariable;

//每次调用MyFunction时,都会在堆栈上分配“ someArgument”
//当MyFunction返回时,“ someArgument”被释放
//范围-只能在MyFunction()中访问
void MyFunction(int someArgument) {

    //首次加载程序时在数据段中静态分配
    //当程序/ DLL退出时释放
    //范围-只能在MyFunction()中访问
    static int someLocalStaticVariable;

    //每次调用MyFunction时都分配在堆栈上
    //当MyFunction返回时取消分配
    //范围-只能在MyFunction()中访问
    int someLocalVariable;

    //每次调用MyFunction时,都会在堆栈上分配一个* pointer *
    //当MyFunction返回时,该指针被释放
    //作用域-只能在MyFunction()中访问指针
    int* someDynamicVariable;

    //此行导致在堆中分配整数的空间
    //当执行此行时。请注意,这不是开始
    //对MyFunction()的调用,就像自动变量一样
    //作用域-只有MyFunction()中的代码才能访问该空间
    // *通过此特定变量*。
    //但是,如果您将地址传递到其他地方,则该代码
    //也可以访问它
    someDynamicVariable = new int;


    //此行为堆中的整数释放空间。
    //如果我们不写它,内存将被“泄漏”。
    //注意堆栈和堆之间的根本区别
    //必须对堆进行管理。堆栈是为我们管理的。
    delete someDynamicVariable;

    //在其他情况下,您无需取消分配该堆空间,
    //可以将地址存储在更永久的位置,以便以后使用。
    //有些语言甚至为您处理了释放问题...但是
    //始终需要在某种机制下在运行时进行维护。

    //当函数返回时,someArgument,someLocalVariable
    //和指针someDynamicVariable被释放。
    // someDynamicVariable指向的空间已经是
    //在返回之前释放。
    return;
}

//请注意someGlobalVariable,someStaticVariable和
// someLocalStaticVariable继续存在,但不存在
//释放,直到程序退出。

C/C++中的一些语法选择加剧了这个问题--例如很多人认为全局变量不是 "静态 "的,因为下面所示的语法。

int var1; //具有全局作用域和静态分配
static int var2; //具有文件范围和静态分配

int main() {return 0;}

有些人认为这些概念是C/C++特有的。其实不然。例如,下面的Python示例说明了所有三种类型的分配(在解释型语言中可能存在一些微妙的差异,我在此不做介绍)。

from datetime import datetime

class Animal:
    _FavoriteFood = 'Undefined' #_FavoriteFood是静态分配的

    def PetAnimal(self):
        curTime = datetime.time(datetime.now()) #curTime是自动分配的
        print("Thank you for petting me. But it's " + str(curTime) + ", you should feed me. My favorite food is " + self._FavoriteFood)

class Cat(Animal):
    _FavoriteFood = 'tuna' #注意,由于我们进行了覆盖,因此Cat类具有其自己的静态分配的_FavoriteFood变量,与Animal的变量不同

class Dog(Animal):
    _FavoriteFood = 'steak' #同样,Dog类获得其自己的静态变量。重要说明-这个静态变量在Dog的所有实例之间都是共享的,因此它不是动态的!


if __name__ == "__main__":
    whiskers = Cat() #动态分配
    fido = Dog() #动态分配
    rinTinTin = Dog() #动态分配

    whiskers.PetAnimal()
    fido.PetAnimal()
    rinTinTin.PetAnimal()

    Dog._FavoriteFood = 'milkbones'
    whiskers.PetAnimal()
    fido.PetAnimal()
    rinTinTin.PetAnimal()

#输出为:
#谢谢你抚摸我。但这是13:05:02.255000,您应该喂我。我最喜欢的食物是金枪鱼
#谢谢你抚摸我。但这是13:05:02.255000,您应该喂我。我最喜欢的食物是牛排
#谢谢你抚摸我。但这是13:05:02.255000,您应该喂我。我最喜欢的食物是牛排
#谢谢你抚摸我。但这是13:05:02.255000,您应该喂我。我最喜欢的食物是金枪鱼
#谢谢你抚摸我。但这是13:05:02.255000,您应该喂我。我最喜欢的食物是牛奶
#谢谢你抚摸我。但这是13:05:02.256000,您应该喂我。我最喜欢的食物是牛奶