阵列,堆和栈和值类型 [英] Arrays, heap and stack and value types

查看:128
本文介绍了阵列,堆和栈和值类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

int[] myIntegers;
myIntegers = new int[100];

在上面的code,是新的INT [100]生成堆上的阵列?从我的CLR通过C#阅读,答案是肯定的。但我不明白,是发生了什么实际的INT的数组中。由于他们是值类型,我猜他们不得不进行装箱,因为我可以,例如,通过myIntegers到程序的其他部分,它会弄乱堆栈,如果他们在它留下所有的时间。还是我错了?我猜他们会仅仅是盒装,并会在堆中生活,只要阵列存在。

In the above code, is new int[100] generating the array on the heap? From what I've read on CLR via c#, the answer is yes. But what I can't understand, is what happens to the actual int's inside the array. As they are value types, I'd guess they'd have to be boxed, as I can, for example, pass myIntegers to other parts of the program and it'd clutter up the stack if they were left on it all the time. Or am I wrong? I'd guess they'd just be boxed and would live on the heap for as long the array existed.

推荐答案

您数组在堆中分配,而整数没有盒装。

Your array is allocated on the heap, and the ints are not boxed.

由于人说,引用类型在堆上分配和值类型在栈上分配的混乱的来源是可能的。这不是一个完全准确的重新presentation。

The source of your confusion is likely because people have said that reference types are allocated on the heap and value types are allocated on the stack. This is not an entirely accurate representation.

所有的局部变量和参数被分配在栈上。这包括值类型和引用类型。两者之间的区别仅是什么的存储的在变量。不出所料,对于价值型的的的类型直接存储在变量,并为引用类型,该类型的值存储在堆中,而引用的该值是什么存储在变量

All local variables and parameters are allocated on the stack. This includes both value types and reference types. The difference between the two is only what is stored in the variable. Unsurprisingly, for a value type, the value of the type is stored directly in the variable, and for a reference type, the value of the type is stored on the heap, and a reference to this value is what is stored in the variable.

这同样适用于字段真。当内存分配给一个聚合类型(类或结构)的实例,它必须包括它的每个实例字段的存储。参考型字段,该存储保持刚值,这将本身在堆上以后分配的参考。对于价值型的字段,这种存储保存实际值。

The same holds true for fields. When memory is allocated for an instance of an aggregate type (a class or a struct), it must include storage for each of its instance fields. For reference-type fields, this storage holds just a reference to the value, which would itself be allocated on the heap later. For value-type fields, this storage holds the actual value.

因此​​,考虑以下类型:

So, given the following types:

class RefType{
    public int    I;
    public string S;
    public long   L;
}

struct ValType{
    public int    I;
    public string S;
    public long   L;
}

每种类型的值将需要16个字节的存储器(假设一个32位字的大小)。字段 I 在每种情况下需要4个字节来存储它的价值,场取值需要4个字节来存储它的参考,和现场需要8个字节来存储它的价值。因此,对于 RefType的 ValType 的值存储看起来是这样的:

The values of each of these types would require 16 bytes of memory (assuming a 32-bit word size). The field I in each case takes 4 bytes to store its value, the field S takes 4 bytes to store its reference, and the field L takes 8 bytes to store its value. So the memory for the value of both RefType and ValType looks like this:


 0 ┌───────────────────┐
   │        I          │
 4 ├───────────────────┤
   │        S          │
 8 ├───────────────────┤
   │        L          │
   │                   │
16 └───────────────────┘

现在,如果你有一个函数三个局部变量的类型, RefType的 ValType INT [] ,就像这样:

Now if you had three local variables in a function, of types RefType, ValType, and int[], like this:

RefType refType;
ValType valType;
int[]   intArray;

那么你的筹码可能是这样的:

then your stack might look like this:


 0 ┌───────────────────┐
   │     refType       │
 4 ├───────────────────┤
   │     valType       │
   │                   │
   │                   │
   │                   │
20 ├───────────────────┤
   │     intArray      │
24 └───────────────────┘

如果您分配的值到本地变量,就像这样:

If you assigned values to these local variables, like so:

refType = new RefType();
refType.I = 100;
refType.S = "refType.S";
refType.L = 0x0123456789ABCDEF;

valType = new ValType();
valType.I = 200;
valType.S = "valType.S";
valType.L = 0x0011223344556677;

intArray = new int[4];
intArray[0] = 300;
intArray[1] = 301;
intArray[2] = 302;
intArray[3] = 303;

那么你的堆栈可能是这个样子:

Then your stack might look something like this:


 0 ┌───────────────────┐
   │    0x4A963B68     │ -- heap address of `refType`
 4 ├───────────────────┤
   │       200         │ -- value of `valType.I`
   │    0x4A984C10     │ -- heap address of `valType.S`
   │    0x44556677     │ -- low 32-bits of `valType.L`
   │    0x00112233     │ -- high 32-bits of `valType.L`
20 ├───────────────────┤
   │    0x4AA4C288     │ -- heap address of `intArray`
24 └───────────────────┘

内存地址0x4A963B68(值 RefType的)会是这样的:


 0 ┌───────────────────┐
   │       100         │ -- value of `refType.I`
 4 ├───────────────────┤
   │    0x4A984D88     │ -- heap address of `refType.S`
 8 ├───────────────────┤
   │    0x89ABCDEF     │ -- low 32-bits of `refType.L`
   │    0x01234567     │ -- high 32-bits of `refType.L`
16 └───────────────────┘

内存地址0x4AA4C288(值 intArray )会是这样的:


 0 ┌───────────────────┐
   │        4          │ -- length of array
 4 ├───────────────────┤
   │       300         │ -- `intArray[0]`
 8 ├───────────────────┤
   │       301         │ -- `intArray[1]`
12 ├───────────────────┤
   │       302         │ -- `intArray[2]`
16 ├───────────────────┤
   │       303         │ -- `intArray[3]`
20 └───────────────────┘

如果你通过了 intArray 另一个函数

现在,值压入堆栈将0x4AA4C288,数组的地址,不会数组的副本。

Now if you passed intArray to another function, the value pushed onto the stack would be 0x4AA4C288, the address of the array, not a copy of the array.

这篇关于阵列,堆和栈和值类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆