C#实例化内存分配问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#实例化内存分配问题相关的知识,希望对你有一定的参考价值。

class A

int a = 12

class B

static void Main(string[] args)

A C1 = new A();
A C2 = new A();
Console.WriteLine("C1.a");
C2.a=6
Console.WriteLine("C2.a");



结果输出的是 12 6 吗?我的问题是当A被实例化两次,a变量是在内存中如何分配的??都分配在堆栈中吗??

首先,堆和栈是两码事。堆(heap)主要用于动态内存分配,而栈(stack)主要是用于函数内自动变量的空间分配。

在C#中,任何引用类型的变量,都是在堆上分配的。(强制声明stackalloc等特殊情况除外)
各种class就是引用类型,所以都是在堆上分配的。

你那个例子,有两个变量,一个是C1,一个是C2,它们各自有一个成员a,彼此互不影响。
二者都分配在堆上,位置不同。所以你C1中a的值是12,C2中a的值是6,二者之间没有影响。追问

先谢谢你,还有一点疑问。书上说 值类型变量存储在栈中。int a 不是值类型吗?

追答

你是什么书?“值类型变量存储在栈中” 这句话不完全正确。只有在函数内部直接定义的值类型,比如你在函数内部定义了一个int a,它才是在stack上面分配的。而对象内部的成员变量(除非静态),不管是值还是引用类型,它都只是整个对象的一部分,而整个对象是在堆上分配的。

感觉你在学C#之前,略微学下C语言会很有助于你对这种概念的理解。这其实是动态内存分配方面的问题,你要是会用C里面的malloc和free,那C#这里面的这些概念的理解都不成问题了。

参考技术A 楼主是新手吧(话说我也是新手来着,从来都没入过门),堆栈的概念都不一样的,怎么会分配堆栈中。
我说说看,不对的话,咱们再讨论:
首先A第一次实例化(也就是C1),那么系统会为它分配一段内存,用来储存数据;(其实你可以在这用指针标记下地址,int* C11=&C1.a)
然后A第二次实例化(也就是C2),那么系统又会为它分配一段内存,用来储存数据;;(其实你依然可以在这用指针标记下地址,int* C22=&C2.a)
然后你调用了,C1.a,也就是说你调用了内存地址为C11的数据,即c1.a的数据存放在C11地址的内存中,你调用了数据,然后输出到屏幕;
然后你为C2.a赋值,即你将内存地址C22的数据从12更改为6;
最后,你调用C2.a输出。
a变量,在两次实例化时,就给各自为其分配了一段内存空间(注解:如果不实例化,那么系统是不会为你分配内存的)。
若有错漏,万望指正。
参考技术B 打印出来结果是:
C1.a
C2.a

╮(╯▽╰)╭怎么会是12 和 6 呢?求教!O(∩_∩)O哈哈~

言归正传吧,不逗你了!
当你每次使用new A()实例化一个对象时,都是调用A类的构造函数在堆中开辟了一个新地址(注意:每次使用都会开辟)。而这个地址中就有一个int变量,这个int变量的值初始化是12,当你对这个int变量的值做修改时,是不会开辟新的地址的!

JAVA中实例化一个对象,成员方法中的参数会在哪分配内存(栈/堆)?

首先内存总体分为了4个部分,包括 stack segment 、heap segment、code segment 、data segment ;
其中我们程序中用关键字new出来的东西都是存放在heap segment;
程序中的局部变量存放在stack segment,这些局部变量是在具体方法执行结束之后,系统自动释放内存资源(而heap segment中的资源需要java垃圾回收机制来处理);
程序中的方法,是内存中的code segment中的,而且是多个对象 共享一个代码空间区域;
static静态变量,需要放在内存中的data segment中,
参考技术A 成员方法?
JAVA中实例化一个对象
会实例该类中的一些成员变量
成员变量也要看是具体对象
还是基础变量
基础变量存储在
栈中
而具体对象引用存在于栈中
具体内容存在堆中
一些特殊的变量
比如静态变量会在类加载的时候在特殊的静态区分配
L楼主说是成员方法???
实例化对象
对成员方法中的参数是不产生影响的
只有实例对象调用方法的时候
其具体涉及到的方法体内的局部变量才会在内存中分配
分配方式依然是:
java基础变量
和java对象
基础变量存储在
栈中
而具体对象引用存在于栈中
具体内容存在堆中
参考技术B 成员方法中的参数会分配在栈中,参数指向堆中的方法体。 参考技术C java那个所有的对象都在堆中,成员方法的参数应该属于临时变量,放在栈中,个人看法,
不过jVM有自动垃圾回收机制,如果放在堆中也无所谓,反正它自己会回收
期待高手更正

以上是关于C#实例化内存分配问题的主要内容,如果未能解决你的问题,请参考以下文章

Java类的实例化对象成员在内存空间怎么分配,调用构造函数又是在内存中怎么分配

C#基础之内存分配

go语言学习笔记 — 基础 — 复合数据类型 — 结构体:实例化结构体 — 为结构体分配内存并初始化

JAVA中实例化一个对象,成员方法中的参数会在哪分配内存(栈/堆)?

C#中字符串的内存分配与驻留池

C# 值类型和引用类型