【问题标题】:Array memory Allocation clarification数组内存分配说明
【发布时间】:2011-10-20 04:59:29
【问题描述】:

今天我正在阅读一个关于数组及其内存分配的 SO 线程。我找到了一个answer,它的解释很简洁,我必须说它很棒。

但是在阅读了那个答案之后,我又得到了几个问题,我一直在问自己关于我刚刚读到的内容。到目前为止,我仍然无法自己回答,也无法谷歌搜索。因此,我需要您的帮助来向我解释这些问题。

  1. 为什么数组的每个内容都是在堆上创建的 存储在堆栈上?只有 2 在值类型的情况下避免装箱?
  2. 如果上面是真的,那么为什么数组首先要在堆上创建 2?

  3. 当他在回答中说 new int[100] 实际上是在堆上创建时,是否在堆上分配了 400 (100 * 4) 字节? 如果是这样,为什么?因为所有值都存储在堆栈中

  4. 如果创建了 1000 项数组,那么究竟如何堆栈才足够存储?我知道 1 MB 是分配的堆栈大小。但在 这种情况下会超过。那么基础是什么??

如果您可能需要,请随时添加您自己的问题或更多信息。

谢谢

【问题讨论】:

  • 请查看最近重复的How are arrays created and accessed
  • 即使认为这个话题似乎是重复的,我更愿意根据我的疑问来扩展关于它的讨论。是的,我阅读了 erics 博客,但我仍然无法说服我的怀疑。因此这个线程。

标签: c# .net


【解决方案1】:

当我们说数组在堆上分配时,这意味着值将在堆中。数组值不存储在堆栈中。我认为这回答了所有 3 个问题。

var myArray = new int[10];

上面的行在堆栈上创建了 myArray variable,但是数组的内存是在堆上分配的,因此存储在其中的所有值也都在堆中。

【讨论】:

  • 但是如果你检查那个答案,他说值存储在堆栈上。如果值类型值存储在堆上,它不需要装箱吗?这是不好的权利。
  • @zenwalker - 你没有抓住重点。当我说 int[] 测试时;我在堆栈上声明了一个能够保存!引用的变量!到一个整数数组。如果我在该语句后面加上 test = new int[10],new 运算符会在堆上保留一块能够容纳 10 个整数的内存块,并返回对该块的引用,然后将其分配给局部变量 test。因此,我为变量 test 分配了一个值,该值是对堆中某个位置的引用,而该位置又保存了一个包含 10 个整数的数组
  • @zenwalker - 拳击是一个不同的过程。使用装箱,您希望能够引用驻留在堆栈上的整数,以便在堆上分配一些空间来保存要引用的变量值的副本。这就是装箱很重的原因,因为它需要在堆上分配和释放小对象。如果您将在堆上创建一个整数数组,则意味着这些整数已经存在,在堆上并且不需要装箱,除非您想从数组中引用单个整数
  • @zenwalker - 也就是说,让我们看一个实际的例子。如果(我的数组 [10] == 5)。在这种情况下,局部变量 myarray(如果正确启动)保存对堆(数组)上的内存块的引用,该内存块保存 int 值。当您说 myarray[10] 时,您可以想到以下发生的事情。 int tempOnStack = myarray[10]。正确创建位置 myarray[10] 的值的副本并将其分配给局部变量。再次没有装箱,因为没有在堆上进行新的分配
  • @zenwalker - 最后,当您为数组中的元素赋值时,会发生同样的事情:myarray[10] = 8;表示值 8 写入堆中 myarray[10] 的位置,为简单起见,可以将其解释为变量 myarray + (10 * sizeof(int)) 的引用内的地址
【解决方案2】:

据我了解,在非正式定义中,值类型存储在本地存储到它们定义的位置。因此,如果在方法中定义了单个值类型,它将存储在堆栈中。如果它被定义为类上的字段,或者在这种情况下,定义为数组中的项,则“父”对象位于堆上,因此值类型也将存储在堆上。

更新

有关值类型与引用类型和堆栈的更多详细信息,请查看 Eric Lippert 的文章:

【讨论】:

  • 即使在阅读了他的博客之后,我还是有点不满意,或者我可能愚蠢地没有达到他的技术水平。因此,如果我们假设值类型存储在堆上,我最终还是会遇到以下问题,它不需要装箱吗?说 int[100] 数组的情况?当我将 int[2000] 项目作为参数传递时怎么样?我想直到运行时才将它作为参考传递,对吗?在 params 方法的情况下会发生什么?如果我将 Method(1,2,3,....5000) 传递给它?还是一样?
  • @zenwalker:正如我在另一条评论中指出的那样,你倒退了。并不是说“堆上的值类型必须装箱”。它是“装箱的值类型必须在堆上”。堆上的值类型可能是装箱的,也可能不是。堆栈上的值类型永远不会被装箱。为什么你错误地认为堆上的值类型必须装箱?我喜欢了解是什么导致人们相信虚假的事情。
猜你喜欢
  • 2021-03-16
  • 2013-01-27
  • 2013-01-24
  • 2016-01-10
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
  • 2022-12-14
  • 2012-03-23
相关资源
最近更新 更多