C # में उपलब्ध विभिन्न डेटा प्रकारों की व्याख्या करने से पहले, यह उल्लेख करना महत्वपूर्ण है कि C # एक दृढ़ता से टाइप की जाने वाली भाषा है। इसका मतलब यह है कि प्रत्येक चर, निरंतर, इनपुट पैरामीटर, रिटर्न प्रकार और सामान्य रूप से प्रत्येक मूल्य का मूल्यांकन करने वाले प्रत्येक अभिव्यक्ति का एक प्रकार होता है।
प्रत्येक प्रकार में ऐसी जानकारी होती है जिसे संकलक द्वारा निष्पादन योग्य फ़ाइल में मेटाडेटा के रूप में एम्बेड किया जाएगा जो कि सामान्य भाषा रनटाइम (CLR) द्वारा टाइप की गई सुरक्षा की गारंटी देने के लिए उपयोग की जाएगी जब यह स्मृति को आबंटित करता है और पुनः प्राप्त करता है।
यदि आप जानते हैं कि एक विशिष्ट प्रकार की कितनी मेमोरी आवंटित की गई है, तो आप निम्न प्रकार से आकार ऑपरेटर का उपयोग कर सकते हैं:
static void Main()
{
var size = sizeof(int);
Console.WriteLine($"int size:{size}");
size = sizeof(bool);
Console.WriteLine($"bool size:{size}");
size = sizeof(double);
Console.WriteLine($"double size:{size}");
size = sizeof(char);
Console.WriteLine($"char size:{size}");
}
आउटपुट प्रत्येक चर द्वारा आवंटित बाइट्स की संख्या दिखाएगा।
int size:4
bool size:1
double size:8
char size:2
प्रत्येक प्रकार से संबंधित जानकारी हैं:
- आवश्यक भंडारण स्थान।
- अधिकतम और न्यूनतम मान। उदाहरण के लिए, Int32 2147483648 और 2147483647 के बीच मूल्यों को स्वीकार करता है।
- आधार प्रकार यह से विरासत में मिला है।
- वह स्थान जहाँ चर के लिए मेमोरी को रन समय पर आवंटित किया जाएगा।
- जिस प्रकार के संचालन की अनुमति है।
प्रकार द्वारा सम्मिलित सदस्य (विधियाँ, क्षेत्र, घटनाएँ, आदि)। उदाहरण के लिए, यदि हम टाइप इंट की परिभाषा की जांच करते हैं, तो हमें निम्नलिखित संरचना और सदस्य मिलेंगे:
namespace System
{
[ComVisible(true)]
public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<Int32>, IEquatable<Int32>
{
public const Int32 MaxValue = 2147483647;
public const Int32 MinValue = -2147483648;
public static Int32 Parse(string s, NumberStyles style, IFormatProvider provider);
...
}
}
मेमोरी प्रबंधन
जब एक ऑपरेटिंग सिस्टम पर कई प्रक्रियाएं चल रही होती हैं और रैम की मात्रा यह सब रखने के लिए पर्याप्त नहीं होती है, तो ऑपरेटिंग सिस्टम रैम के साथ हार्ड डिस्क के कुछ हिस्सों को मैप करता है और हार्ड डिस्क में डेटा स्टोर करना शुरू कर देता है। ऑपरेटिंग सिस्टम विशिष्ट तालिकाओं की तुलना में उपयोग करेगा जहां अनुरोध को करने के लिए वर्चुअल पतों को उनके संवाददाता भौतिक पते पर मैप किया जाता है। मेमोरी को प्रबंधित करने की इस क्षमता को वर्चुअल मेमोरी कहा जाता है।
प्रत्येक प्रक्रिया में, उपलब्ध वर्चुअल मेमोरी को निम्नलिखित 6 अनुभागों में व्यवस्थित किया जाता है, लेकिन इस विषय की प्रासंगिकता के लिए, हम केवल स्टैक और हीप पर ध्यान केंद्रित करेंगे।
स्टैक
एक LIFO है (पिछली बार, पहले आउट) डेटा संरचना, ऑपरेटिंग सिस्टम पर एक आकार-निर्भर के साथ (एआरएम के लिए, x86 और x64 मशीनों के लिए विंडोज 1MB आरक्षित है, जबकि लिनक्स 2MB से 8MB तक आरक्षित है संस्करण)।
मेमोरी का यह खंड सीपीयू द्वारा स्वचालित रूप से प्रबंधित किया जाता है। हर बार जब कोई फ़ंक्शन एक नया चर घोषित करता है, तो संकलक स्टैक पर उसके आकार के रूप में एक बड़ा मेमोरी ब्लॉक आवंटित करता है, और जब फ़ंक्शन खत्म हो जाता है, तो चर के लिए मेमोरी ब्लॉक डीलॉक्लेट किया जाता है।
हीप
मेमोरी का यह क्षेत्र सीपीयू द्वारा स्वचालित रूप से प्रबंधित नहीं किया जाता है और इसका आकार स्टैक से बड़ा है। जब नया कीवर्ड लगाया जाता है, तो संकलक पहले मुक्त मेमोरी ब्लॉक की तलाश शुरू करता है जो अनुरोध के आकार को फिट करता है। और जब यह पता चलता है, तो यह अंतर्निहित C फ़ंक्शन मॉलोक () का उपयोग करके आरक्षित किया जाता है और उस स्थान पर सूचक लौटाता है। अंतर्निहित C फ़ंक्शन मुक्त () का उपयोग करके मेमोरी के ब्लॉक को डील करना भी संभव है। यह तंत्र मेमोरी विखंडन का कारण बनता है और मेमोरी के सही ब्लॉक तक पहुंचने के लिए पॉइंटर्स का उपयोग करना पड़ता है, यह रीड या राइट ऑपरेशन करने के लिए स्टैक की तुलना में धीमा होता है।
कस्टम और बिल्ट-इन प्रकार
जबकि C # बिल्ट-इन प्रकारों का एक मानक सेट प्रदान करता है जो पूर्णांक, बूलियन, पाठ वर्णों का प्रतिनिधित्व करता है, और इसी तरह, आप अपने स्वयं के प्रकार बनाने के लिए संरचना, वर्ग, इंटरफ़ेस और एनम जैसे निर्माणों का उपयोग कर सकते हैं।
संरचना निर्माण का उपयोग करते हुए कस्टम प्रकार का एक उदाहरण है:
struct Point
{
public int X;
public int Y;
};
मूल्य और संदर्भ प्रकार
हम C को निम्न श्रेणियों में वर्गीकृत कर सकते हैं:
मान प्रकार के
मान System.ValueType वर्ग से प्राप्त होते हैं और इस प्रकार के चर स्टैक में अपने मेमोरी आवंटन के भीतर उनके मान होते हैं। मूल्य प्रकार की दो श्रेणियां हैं संरचना और एनम।
निम्न उदाहरण बूलियन के सदस्य को दर्शाता है। जैसा कि आप देख सकते हैं कि System.ValueType वर्ग का कोई स्पष्ट संदर्भ नहीं है, ऐसा इसलिए होता है क्योंकि यह वर्ग संरचना द्वारा विरासत में मिला है।
namespace System
{
[ComVisible(true)]
public struct Boolean : IComparable, IConvertible, IComparable<Boolean>, IEquatable<Boolean>
{
public static readonly string TrueString;
public static readonly string FalseString;
public static Boolean Parse(string value);
...
}
}
संदर्भ प्रकार
दूसरी ओर, संदर्भ प्रकार में एक चर में संग्रहीत वास्तविक डेटा नहीं होता है, लेकिन ढेर का मेमोरी पता जहां मूल्य संग्रहीत होता है। संदर्भ प्रकारों की श्रेणियां वर्ग, प्रतिनिधि, सरणियाँ और इंटरफ़ेस हैं।
रन समय में, जब एक संदर्भ प्रकार चर घोषित किया जाता है, तो इसमें मूल्य शून्य होता है जब तक कि कोई वस्तु जो नए कीवर्ड का उपयोग करके बनाई गई है, उसे सौंपी जाती है।
निम्न उदाहरण जेनेरिक प्रकार सूची के सदस्यों को दर्शाता है।
namespace System.Collections.Generic
{
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(typeof(Generic.Mscorlib_CollectionDebugView<>))]
[DefaultMember("Item")]
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>
{
...
public T this[int index] { get; set; }
public int Count { get; }
public int Capacity { get; set; }
public void Add(T item);
public void AddRange(IEnumerable<T> collection);
...
}
}
यदि आप किसी विशिष्ट ऑब्जेक्ट की मेमोरी एड्रेस का पता लगाना चाहते हैं, तो क्लास System.Runtime.InteropServices अप्रबंधित मेमोरी से प्रबंधित ऑब्जेक्ट तक पहुंचने का एक तरीका प्रदान करता है। निम्नलिखित उदाहरण में, हम एक स्ट्रिंग को हैंडल आवंटित करने के लिए स्थैतिक विधि GCHandle.Alloc () का उपयोग करने वाले हैं और फिर इसका पता पुनः प्राप्त करने के लिए AddrOfPinnedObject विधि।
string s1 = "Hello World";
GCHandle gch = GCHandle.Alloc(s1, GCHandleType.Pinned);
IntPtr pObj = gch.AddrOfPinnedObject();
Console.WriteLine($"Memory address:{pObj.ToString()}");
आउटपुट होगा
Memory address:39723832
संदर्भ
आधिकारिक दस्तावेज: https://docs.microsoft.com/en-us/cpp/build/reference/stack-stack-allocations?view=vs-2019