مهم :
همانطور که قبلا استاد گفته بودند ، struct و class ها ، هیچ ربطی به حافظه ی stack و heap نباید داشته باشند . یعنی بهتر اینکه به برنامه نویس مربوط نمیشود .
شی struct ، هر جایی که باشد (مثلا به عنوان مقدار یک متغییر باشد یا به عنوان مقدار عضوی از آرایه و ...) ، در همان حافظه کلا قرار میگیرد (چه در حافظه ی stack باشد یا heap) . اما reference type ها ، بصورت اشاره گر ، به حافظه ی دیگری اشاره میکنند .
مثلا متغییر محلی int a = 1; که از نوع struct هست ، در حافظه ی stack قرار میگیرد (که البته مهم هم نیست فرضا در استک باشد یا در هیپ ؛ یعنی صِرفِ اینکه چون در حافظه ی استک هست ، ممکن است دلیل بر این نباشد که سرعت دسترسی بالاتری دارد) .
اما آرایه ای از int ( یعنی int[] ) ، چون آرایه ، یک کلاس هست ، اشاره گر به حافظه ی heap دارد . اما آیتم هایش که از نوع struct هستند ، باز در همان آدرس از حافظه ی heap ای که آرایه قرار دارد ، قرار میگیرد . یعنی در این صورت ، آیتم های آرایه که از نوع struct هستند ، در حافظه ی stack قرار نمیگیرند .
مثلا در آرایه ی زیر :
C#:
int[] abc = new int[]{10, 20, 30};
فرضا اگر آرایه ی abc ، اشاره گر به خامه ی 1000 در حافظه ی heap باشد ، ایندکس 0 از این آرایه ، 4 بایت فضا دارد که مقدار int در آن هست (و همینطور بقیه ی ایندکس هایش هم 4 بایت فضا دارند). یعنی در اینجا شی int ، در حافظه ی stack قرار ندارد ؛ بلکه داخل حافظه ی heap قرار دارد .
(یعنی این طور نیست که چون int از نوع value type و struct هست ، پس در اینجا هم در حافظه ی stack قرار بگیرد و چون در این صورت ، آدرس stack ، جدای از حافظه ی heap هست ، پس ، آیتم های این آرایه ، اشاره گری به حافظه ی stack ئه نخ باشند) .
در مورد بقیه ی structهایی که خودمان بسازیم هم همینطور هست .
یعنی آن نوع های struct هم که ما تعریف میکنیم ، وقتی به عنوان آیتم های آرایه تعریف میشوند ، درون خود حافظه ی مربوط به آرایه (یعنی در heap) حافظه اشغال میکنند (یعنی در حافظه ی دیگری مثل stack قرار نمیگیرند که آیتم های آرایه ، اشاره گری به آن حافظه شوند) :
C#:
PicInfo[] ints = new PicInfo[3] { new PicInfo(1, 2), new PicInfo(20, 21), new PicInfo(30, 31) };
PicInfo[] ints_22 = new PicInfo[ints.Length];
ints.CopyTo(ints_22, 0);
ints[0] = new PicInfo(1500, 1600);
و
C#:
internal struct PicInfo
{
public int x;
public int y;
public PicInfo(int x, int y)
{
this.x = x;
this.y = y;
}
}
یعنی struct ها در هر حافظه ای که تعریف شوند ، همانجا قرار میگیرند و بصورت اشاره گر استفاده نمیشوند که این باعث میشود که چون پردازنده ، مجددا به سراغ حافظه ی دیگری نمیرود ، سرعت دسترسی اش بیشتر از reference type ها شود .
با تشکر از استاد و بقیه ی دوستان .