C# 引用类型和值类型的堆栈分布

本文探讨了引用类型与值类型在不同上下文中的内存分配位置,通过具体实例解释了结构体作为值类型在栈上分配,而其内部的引用类型则在堆上分配的原理,展示了浅拷贝的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、引用类型一定放在堆上吗?

面试官提到这个问题的时候,我第一反应当然说不是,然后我就说引用类型可能持有值类型的对象,而该对象存放在栈上……然后我开始觉得不妥……面试官接着问,那么在方法体结束后,栈上的临时空间释放了,那么该引用类型所持有的对象去哪里了呢……这时候意识到可能回答错误了,但是我就着这个问题回答,如果引用类型持有了某个值类型对象,那么会将其装箱在引用类型的堆内存中,当栈上空间释放后引用类型的值类型对象还是存在只不过其值为空……(那么该引用类型所持有的值对象不是一样在堆上了吗)

可能面试官就是想把我拉回到正确的答案上来,我的这一番回答也渐渐说明了一个问题:引用类型总是放在堆上的

引用类型就是总是在堆上的,而值类型的分配位置取决于他声明的位置,如果值类型声明在引用类型中,那么它就是在堆上的,如果在结构中,那么它就是分配在栈上的。

做一个简单的例子,如果我声明一个结构,结构中包含了引用类型,那么按照这样的操作,会输出什么?

struct Person
    {
        public CPerson cperson;
        public int age;
        public Sex sex; 
        public Person(int _age,Sex _sex)
        {
            age = _age;
            sex = _sex;
            cperson = new CPerson("CPerson");
        }

    }
 class Program
    {
        public static void Main()
        {
            Person p1 = new Person(10,Sex.male);
            Person p2 = p1;
            p2.age = 12;
            p2.cperson.name = "sperson";
            p1.cperson.Print();
            p2.cperson.Print();
            Console.WriteLine(p1.age);
        }
    }

这里Sex是一个枚举类型。

结果输出:

sperson
sperson
10

这充分说明struct是值类型,像int一样赋值,在栈上新生成了对象,但是其中的引用类型,却只保留了其指针,指向了堆中的CPerson对象,所以最终的结果就是有两个Person的结构体对象,和一个CPerson引用类型对象,这两个结构中的cperson指针都指向这个堆中的对象。这就是一种浅拷贝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值