何时为变量分配内存,在声明时还是在初始化时?

Posted

技术标签:

【中文标题】何时为变量分配内存,在声明时还是在初始化时?【英文标题】:When will the memory be allocated for the variables, at declaration or at initialization? 【发布时间】:2020-04-25 18:25:59 【问题描述】:

考虑 C# 中的两种情况

案例一

int a;
a = 10;

内存将在何时何地分配给a

案例 2

int a = 10;

这两种情况有什么区别,它们在内存分配方面有何不同?

【问题讨论】:

据我所知,内存在达到作用域时会在栈中分配 Case 1 和 Case 2。编译成 IL 后就没有区别了。 【参考方案1】:

在执行序言代码的那一刻,局部变量被分配在调用堆栈上。因此,在您的函数甚至被调用之前,在当前堆栈帧中为 int 变量(和任何参数)保留了 4 个字节。当堆栈帧被擦除时,该内存就消失了,这就是函数调用结束时发生的情况。这与您在任何基于堆栈的编程语言中看到的行为相同(大部分情况下)。对于此类一般性问题,您最好使用谷歌搜索事情的运作方式。

只有在使用 new 时才会分配额外的内存。在使用 new 时,内存被分配到堆中,并返回对局部变量的引用(在函数调用时分配)。

所以,根据您的问题,这取决于。

局部变量/参数 - 在函数序言代码中 Ref 实例 - 在您调用 new 时 类型中的字段 - 在创建类型实例时(通过新建) 初始化是一个完全独立的过程。 ref 实例需要更深入的讨论。给定以下代码,有 2 个分配。

MyClass instance = new MyClass();

第一次分配用于局部变量实例。作为 ref 变量,它占用堆栈上的 4/8 个字节。第二次分配发生在执行 new 的时刻。堆中的空间是为 MyClass 分配的,你会得到一个引用,然后分配给你的(已经分配的)局部变量。

当函数调用结束时,实例变量被擦除(因为堆栈帧已经消失),而 MyClass 的实例将一直挂起,直到 GC 运行以清理它。

【讨论】:

【参考方案2】:

内存是在声明变量时分配的,而不是在初始化时分配的。所以在第一个例子中,当到达第一行时,内存将被分配,而在第二个例子中,声明和初始化在同一行,所以显然内存将被分配。

编辑:当你声明一个引用类型的局部变量时,堆栈上的内存被分配给这个引用。当您初始化该变量时,会为该对象分配堆上的内存。

【讨论】:

这是错误的。请阅读value 和reference 类型。 @oleksa 值类型与引用类型与为局部变量分配内存无关。当您创建引用类型的局部变量并将其设置为null 时,仍会为引用本身分配内存。 Memory is allocated when a variable is declared, not when it's initialized. 你忘了添加“值类型”这就是重点 @oleksa 也许,我不清楚。我的意思是在声明变量时分配内存在堆栈上。如果它是一个值类型,那么这就是它所需要的。如果它是引用类型,那么对象的内存是在初始化时分配的,但引用本身的内存是在声明时分配的。我将编辑我的答案以使其更清楚。

以上是关于何时为变量分配内存,在声明时还是在初始化时?的主要内容,如果未能解决你的问题,请参考以下文章

第十二章 类和动态内存分配

C++中内存分配问题

TSQL 何时为存储过程中的变量(和表变量)分配内存

类中声明的变量的内存分配

java中创建数组时怎么分配内存?

传递动态内存