堆和堆栈如何为C#中的struct实例和成员工作? [英] How does the heap and stack work for instances and members of struct in C#?

查看:88
本文介绍了堆和堆栈如何为C#中的struct实例和成员工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在读一本书,上面写着:

表示结构实例的变量不包含指向实例的指针;该变量包含实例本身的字段.由于变量包含实例的字段,因此不必取消引用指针即可操作实例的字段.以下代码演示了引用类型和值类型的不同之处

  class SomeRef {public Int32 x;}struct SomeVal {public Int32 x;}静态void ValueTypeDemo(){SomeRef r1 =新的SomeRef();//分配在堆中SomeVal v1 =新的SomeVal();//分配在堆栈上r1.x = 5;//指针取消引用v1.x = 5;//更改为堆栈} 

我来自C语言背景,对结构变量 v1 有点困惑,我觉得 v1.x = 5; 仍然像数组一样涉及指针取消引用C中的变量是指向该数组中第一个元素的地址的指针,我觉得 v1 必须是一个指向<中第一个字段的地址(当然是堆栈,而不是堆)的指针.code> SomeVal ,如果我的理解是正确的,那么 v1.x = 5; 也必须涉及指针取消引用吗?如果不是这样,那么当我们要访问结构中的随机字段时,由于编译器需要生成该字段的偏移量,那么如何不包含指针呢?

解决方案

相关答案:

如何使用堆中的类型对象找到结构实例的虚拟方法?

正如@ Damien_The_Unbeliever所说,以下内容仅对当前的计算技术有效,因为.NET是一个虚拟平台.实际上,自从CPU开始并且发明了堆栈寄存器以来,在类似Intel的微处理器(x86,x32,x64和类似处理器)上,其行为便是如此.但是将来,潜在的事物可能与量子等其他任何技术世代都不一样.

作为类成员的struct实例与对象本身一起分配,因此在堆中,但在方法中声明的局部struct变量在堆栈中分配.

此外,作为方法的参数传递的变量始终使用堆栈:对引用以及结构的内容进行推入和弹出,因此建议不要过度使用结构结构和匿名类型,并且不要太限制大.

为简化起见,请想象一下,堆是整个房间,而堆是这个房间的橱柜.

此橱柜用于局部值类型变量和用于运行程序的引用,以及在方法之间传递数据以及在这些方法是函数而非过程时获取这些方法的结果:引用,值类型,整数类型,将结构内容,匿名类型和委托作为临时容器从此橱柜中推入和弹出.

该空间用于对象本身(我们传递对象的引用),除了不在对象中的单独结构(我们传递所有struct内容,传递类中的结构时,情况都是一样的),通过整个结构作为副本).

例如:

  class MyClass{MyStruct MyVar;} 

是结构变量不单独"在任何地方创建时,都会在对象的头部创建.

但是:

  void MyMethod(){MyStruct MyVar;} 

是本地的单独的"吗?在堆栈中创建的结构的实例以及整数.

因此,如果一个类有10个整数,则在调用方法时(x32上为4字节,x64上为8字节),仅将引用推入堆栈.但是,如果它是一个结构,则需要推送10个整数(x32和x64上为40个字节).

换句话说,如您所写:因此,仅结构实例(因此,分配给结构类型的局部变量)不会存储在堆中.但是类的成员(因此已分配给结构类型的字段)存储在堆中..

说:

    使用 MOV 操作码和等效代码(虚拟或目标机器码)通过直接内存访问来访问堆中结构的
  • 成员(整数和引用指针值").

  • 使用堆栈寄存器base + offset访问堆栈中结构的成员.

第一个慢,第二个快.

此对象的内存看起来如何?

什么是堆栈和堆?在哪里?

在c Sharp中堆叠并堆积

内存分配:堆栈还是堆?

堆栈和堆分配

堆栈和堆内存

为什么返回方法在正常情况下只是一种参数?

CIL指令列表

.NET OpCodes类

堆栈注册

堆栈的概念及其在堆栈中的使用微处理器

基于堆栈的CPU组织介绍

堆栈在微处理器中的作用是什么?

为了更好地理解和提高您的计算技能,您可能会发现研究汇编语言以及 CPU 的工作方式.您可以从 IL 现代英特尔,但它可能更简单,更具格式性且补充以从过去开始 8086到i386/i486 .

I'm reading a book which says:

The variable representing an struct instance doesn’t contain a pointer to an instance; the variable contains the fields of the instance itself. Because the variable contains the instance’s fields, a pointer doesn’t have to be dereferenced to manipulate the instance’s fields. The following code demonstrates how reference types and value types differ

class SomeRef { public Int32 x; }
struct SomeVal { public Int32 x; }

static void ValueTypeDemo() {
   SomeRef r1 = new SomeRef();        // Allocated in heap
   SomeVal v1 = new SomeVal();        // Allocated on stack
   r1.x = 5;                          // Pointer dereference
   v1.x = 5;                          // Changed on stack
}

I'm from C background and little bit confused about the struct variable v1, I feel like v1.x = 5; still involve pointer dereference just like an array variable in C is a pointer to the address of first element in that array, I feel like v1 must be a pointer that points to the address(of stack, not heap of course) of first field in SomeVal, if my understanding is correct, then v1.x = 5; must involve pointer dereference too? If not, how a pointer is not involved if we want to access an random field in a struct as the compiler needs to generate the offset to the field, still a pointer has to be involved?

解决方案

Related answer:
How does a struct instance's virtual method get located using its type object in heap?

As said by @ Damien_The_Unbeliever, what follows is only valid for current computing technologies because .NET is a virtual platform. Actually and on Intel-like microprocessors (x86, x32, x64 and similar) since the CPU beginning and the invention of the stack registers, the behavior is like it is. But in the future, underlying things may be different with any other tech gen like quantum.

Instances of struct as members of a class are allocated with the object itself, so in the heap, but a local struct variable declared in a method is allocated in the stack.

Also, variables passed as parameters for a method always use the stack: reference as well as content of structures are PUSHed and POPed, therefore the limit of structures and anonymous types that are recommended to not be over used and to not be too big.

To simplify things and to understand, imagine that the heap is a whole room and the stack is a cupboard in this room.

This cupboard is for local value-types variables and references used to run the program, as well as to pass data between methods and to get results of these methods when they are functions and not procedures: references, value types, integral types, structs content, anonymous types and delegates are PUSHed and POPed to and from this cupboard as a temporary container.

The room is for objects themselves (we pass references of objects), except structs alone which are not in objects (we pass all the struct content, and it is the same when we pass a struct that is in a class, we pass the entire struct as a copy).

For example:

class MyClass
{ 
  MyStruct MyVar;
}

Is a struct variable "not alone" created in the head with the object when created anywhere.

But:

void MyMethod()
{ 
  MyStruct MyVar;
}

Is a local "alone" instance of the struct created in the stack as well as integers.

Thus if a class has 10 integers, only the reference is PUSHed in the stack when calling a method (4 bytes on x32 and 8 bytes on x64). But if it were a struct, it requires to PUSH 10 integers (40 bytes on x32 as well as x64).

In other words as you wrote: So then struct instances alone (thus, assigned to a local variable of struct type) are not stored in the Heap. But members of a class (thus, assigned to a field of struct type) are stored in the Heap.

That said:

  • Members (integral numeric and references pointer "values") of a struct in the heap are accessed using direct memory access using MOV opcodes and equivalent (virtual or targetted machine code).

  • Members of a struct in the stack are accessed using the stack register base+offset.

First is slow and second is faster.

How would the memory look like for this object?

What and where are the stack and heap?

Stack and heap in c sharp

Memory allocation: Stack vs Heap?

Stack and Heap allocation

Stack and Heap memory

Why methods return just one kind of parameter in normal conditions?

List of CIL instructions

.NET OpCodes Class

Stack register

The Concept of Stack and Its Usage in Microprocessors

Introduction of Stack based CPU Organization

What is the role of stack in a microprocessor?

To understand better and to improve your skills in computing, you may found interesting to investigate what is assembly language and how work the CPU. You can start with IL and modern Intel but it may be simpler, formative and complementary to start from the past 8086 to i386/i486.

这篇关于堆和堆栈如何为C#中的struct实例和成员工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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