Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 堆栈内存是否仅用于指针和堆对象?_C#_Pointers_Memory_Heap Memory_Stack Memory - Fatal编程技术网

C# 堆栈内存是否仅用于指针和堆对象?

C# 堆栈内存是否仅用于指针和堆对象?,c#,pointers,memory,heap-memory,stack-memory,C#,Pointers,Memory,Heap Memory,Stack Memory,首先,我目前在C#工作,我一直在阅读有关内存管理的书籍。到目前为止,我已经阅读了有关堆栈溢出的一些很好的答案,解释了堆栈内存和托管堆内存之间的区别。大多数答案都声明: int x=5,您正在堆栈内存中为x类型分配足够的内存。 我了解它的工作原理和范围,但是当我阅读堆内存的解释时,我感到困惑。 如果你说的是int x=5,因为int是System.Int32的别名,那么x从技术上讲不是指向System.Int32结构的新实例的指针吗?如果是这样的话,它会不会存储在堆内存中,因为堆内存用于实例对象。

首先,我目前在C#工作,我一直在阅读有关内存管理的书籍。到目前为止,我已经阅读了有关堆栈溢出的一些很好的答案,解释了堆栈内存和托管堆内存之间的区别。大多数答案都声明:
int x=5
,您正在堆栈内存中为
x
类型分配足够的内存。

我了解它的工作原理和范围,但是当我阅读堆内存的解释时,我感到困惑。

如果你说的是
int x=5
,因为
int
System.Int32
的别名,那么
x
从技术上讲不是指向
System.Int32
结构的新实例的指针吗?如果是这样的话,它会不会存储在堆内存中,因为堆内存用于实例对象。

在教程中,它声明(对于行
class1 cls1=new class1()
): ... 在堆栈上创建一个指针,而实际对象存储在另一种称为“Heap”的内存位置。
按照这种逻辑,不是所有的东西都存储在堆上,只有指针存储在堆栈上吗?示例为
System.String
System.Int64
System.Boolean
System.Decimal
等的新实例。

我想我理解它,但我不清楚,所以我希望有人能解释一下堆栈是否只用于指针,或者我误解了哪个部分。提前感谢。

您可能需要检查以了解什么存储在何处以及如何存储:

int x = 1; // 32 bits holding an integer in the stack
System.Object bo = x; // 32+some more bits are on the heap to hold the "boxed" (wrapped to be kept on the heap) integer value
System.Object ho = new Object(); // some bits are created on the heap right from the start
简单地说,有两种类型的对象:类和结构。类(引用类型)将存储在堆上,并有一个指向它们的指针,而结构将存储在堆栈中(结构可以重新定位到堆上,但包装(“装箱”)它们的开销很小)


如果您真的需要/想要理解CLR一般是如何工作的,请考虑阅读“CR通过C.*”(李希特)。

您可以使用以下规则:如果它是一个结构(包括基元类型),那么它就被分配到声明的地方,否则就分配给堆中对象的指针。 可能的地点包括:

  • 对于局部变量,它是一个堆栈。请注意,物理值可以存储在CPU寄存器中,而不是堆栈中
  • 对于类字段,它位于为类实例在堆中分配的连续内存块内
  • 对于静态字段,它在加载程序堆中作为类型元数据的一部分进行分配(如果我错了,请纠正我)

  • 警告:这只是一个基本的、不全面的解释,对发生的事情有一个基本的了解。现实更为复杂。局部变量可以被提升并移动到堆中,优化器可以完全消除它们,等等。

    系统。Int32
    是一个结构,而不是一个类。因此,作为本地,它可能会在堆栈上分配。请记住,.NET CLR正在更改,“已分配的堆”和“已分配的堆栈”之间的行将继续变得更模糊。教程是错误和不完整的。@Nathangrad结构在C#中不能为null。结构是值类型。没有要为null的引用。C#编译器可能会在“使用未初始化变量”时出错,但这只是编译器试图提供帮助的地方。然后,如果您有很多空闲时间,您可以阅读ECMA规范。如果您想添加更多,您应该编辑您的答案。不需要自己直接评论(问题/答案),这比“值类型存储在堆栈上,引用类型存储在堆上”更复杂。
    类[…]在堆栈中有指向它们的指针
    指针不一定在堆栈上。它可能在堆栈上,适用于任何值,正如Joshua所指出的,这也会使同一句话的后半部分出错。正如我(和Joshua)之前所说,句子的其余部分仍然是错误的。对于未加权的局部变量,它可能是堆栈。如果您想更精确,请参阅注释中链接到的Eric Lippert帖子。是的,已提升的变量成为显示(闭包)类的字段,即使未提升该变量,也可能无法使用堆栈。它可能严格使用注册,也可能被完全优化。我刚刚用谷歌搜索了你在答案中使用的80%的技术术语,但我想我理解。谢谢