当采用默认构造函数List<int> value = new List<int>();实例化一个List<T>对象时,.Net Framework只是在内存中申请了一块内存来存放List<T>对象本身(不包含List当中的Items元素)。

当为List<T>对象添加第一个Item元素时,List<T>对象会申请能存储4个Item元素的内存空间,然后将Item元素存放在申请的空间里。

List<T>对象有一个Capacity属性用来表示当前List<T>对象的容量(即当前用于存放Item的内存空间能存放的Item的个数),可以手动的设置它来设定List<T>的容量(Capacity的改变将会导致重新申请内存)。

当List<T>对象的Item元素数量超过了Capacity的数量时,List<T>对象会重新申请一块大小是原来Capacity的两倍的内存空间,然后将当前所有Item元素以及待添加元素复制到新的内存空间中。——转载 cdsn  daone

 

自己的理解:

每次创建一个list<T>的的对象系统都会申请一块大小为Capacity内存,只有在对象中的元素个数超过Capacity时,对象会重新申请大小为原来两倍的内存空间,并将当前所有Item元素以及待添加元素复制到新的内存空间中,这样的操作类似与动态数组,虽然效率不高,但是能节约不必要的内存;

而在list<T>对象里,对象以一个一个的节点保存 ,大致可以将节点分为三个部分 :前驱指针(pre)后驱指针(next)和数据域(data);指针时系统内部处理的,不需要我们去赋值或者给其指向,我们需要注意的只有数据域(data)。这里存储的数据类型和创建对象时T类型必须是一致的,push操作和pop操作的对象也就是data中的内容,对节点本身的内存不会有影响;比如T时一个指针类型,我们创建一个节点时,数据域存储的就是一个指针,也就是一个地址,如果这个指针是在堆区申请的内存,那么在删除该节点之前,必须将它在堆区的内存释放,指针置空之后,才能对节点进行删除,否则就会导致内存泄。

关于迭代器,它是的功能类似与指针,但是一般只用于遍历,比如迭代器 it,*it得到的就是他指向的节点的数据域,如果数据域是一个指针,那么它得到的就是一个指针;假如我们push_front(*it),相当于将一个指针存入该节点的数据域。

List容器内存分配原则(部分转载至CSDN——daone)_内存空间