<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Memory Management on kenji.blog</title><link>http://kenji.blog/hi/tags/memory-management/</link><description>Recent content in Memory Management on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>hi</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 07:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/hi/tags/memory-management/index.xml" rel="self" type="application/rss+xml"/><item><title>मेमोरी लीक को रोकने के लिए स्मार्ट पॉइंटर्स (std::unique_ptr / shared_ptr) का उपयोग गाइड</title><link>http://kenji.blog/hi/p/cpp-smart-pointers-guide-unique-shared-ptr/</link><pubDate>Sat, 12 Sep 2026 07:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/cpp-smart-pointers-guide-unique-shared-ptr/</guid><description>&lt;img src="http://kenji.blog/p/cpp-smart-pointers-guide-unique-shared-ptr/img/eyecatch.jpg" alt="Featured image of post मेमोरी लीक को रोकने के लिए स्मार्ट पॉइंटर्स (std::unique_ptr / shared_ptr) का उपयोग गाइड" />&lt;p>C++ में मेमोरी प्रबंधन लंबे समय से डेवलपर्स के लिए सबसे बड़ी चुनौतियों में से एक रहा है। मैन्युअल &lt;code>new&lt;/code> और &lt;code>delete&lt;/code> पर निर्भर पारंपरिक मेमोरी प्रबंधन शैली, मेमोरी लीक, डैंगलिंग पॉइंटर्स और डबल फ्री जैसे गंभीर बग्स का कारण बनती थी। हालाँकि, मॉडर्न C++ (C++11 और उसके बाद) के आगमन के साथ, स्थिति नाटकीय रूप से बदल गई है। इसका मुख्य केंद्र &amp;ldquo;स्मार्ट पॉइंटर्स (Smart Pointers)&amp;rdquo; है।&lt;/p>
&lt;p>इस लेख में, हम मेमोरी लीक को जड़ से खत्म करने और सुरक्षित तथा कुशल संसाधन प्रबंधन प्राप्त करने के लिए शक्तिशाली उपकरणों, जैसे &lt;code>std::unique_ptr&lt;/code>, &lt;code>std::shared_ptr&lt;/code> और &lt;code>std::weak_ptr&lt;/code> के तंत्र और उन्नत उपयोग तकनीकों के बारे में विस्तार से चर्चा करेंगे। इसमें आंतरिक कार्यान्वयन (कंट्रोल ब्लॉक और एटॉमिक ऑपरेशंस), प्रदर्शन पर प्रभाव, और गणितीय मॉडल का उपयोग करके संदर्भ गणना (reference counting) के सूत्रीकरण पर भी गहराई से बात की जाएगी।&lt;/p>
&lt;h2 id="1-परचय-c-ममर-परबधन-क-अधकर-यग-और-मडरन-c-क-सबह">1. परिचय: C++ मेमोरी प्रबंधन का अंधकार युग और मॉडर्न C++ की सुबह
&lt;/h2>&lt;p>पहले के C++ विकास में, डेवलपर्स खुद ही हीप पर आवंटित मेमोरी को मुक्त करने के लिए जिम्मेदार होते थे।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">legacy_function&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">ptr&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// ... कुछ प्रक्रिया ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">some_condition&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// मेमोरी लीक होता है! delete कॉल नहीं किया गया
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">delete&lt;/span> &lt;span class="n">ptr&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>ऊपर दिए गए कोड में, यदि कोई अपवाद (exception) आता है या जल्दी रिटर्न होता है, तो &lt;code>delete&lt;/code> छोड़ दिया जाता है, जिससे मेमोरी लीक होती है। इसे रोकने के लिए इस्तेमाल होने वाला प्रतिमान &amp;ldquo;RAII (Resource Acquisition Is Initialization)&amp;rdquo; है। RAII एक ऐसी तकनीक है जो संसाधन आवंटन को ऑब्जेक्ट के इनिशियलाइज़ेशन (कंस्ट्रक्टर) से और संसाधन की मुक्ति को ऑब्जेक्ट के विनाश (डिस्ट्रक्टर) से जोड़ती है। स्मार्ट पॉइंटर्स, मेमोरी प्रबंधन में इस RAII इडियम को लागू करने वाले मानक लाइब्रेरी क्लास स्टैक हैं।&lt;/p>
&lt;h2 id="2-stdunique_ptr-शनय-ओवरहड-क-सथ-वशष-सवमतव-exclusive-ownership">2. &lt;code>std::unique_ptr&lt;/code>: शून्य ओवरहेड के साथ विशेष स्वामित्व (Exclusive Ownership)
&lt;/h2>&lt;p>&lt;code>std::unique_ptr&lt;/code> एक स्मार्ट पॉइंटर है जिसका डायनामिक रूप से आवंटित ऑब्जेक्ट्स पर &amp;ldquo;विशेष स्वामित्व (Exclusive Ownership)&amp;rdquo; होता है। किसी दिए गए संसाधन का मालिक हमेशा केवल एक ही &lt;code>unique_ptr&lt;/code> हो सकता है।&lt;/p>
&lt;h3 id="21-शनय-ओवरहड-zero-overhead-क-सदधत">2.1 शून्य ओवरहेड (Zero Overhead) का सिद्धांत
&lt;/h3>&lt;p>&lt;code>std::unique_ptr&lt;/code> का सबसे बड़ा आकर्षण इसका प्रदर्शन है। कस्टम डिलीटर (deleter) के बिना डिफ़ॉल्ट स्थिति में, &lt;code>std::unique_ptr&lt;/code> का आकार कच्चे पॉइंटर (Raw Pointer) के बिल्कुल समान होता है। इसमें कोई अनावश्यक सदस्य चर (member variables) नहीं होते हैं, और वर्चुअल फ़ंक्शन का भी उपयोग नहीं किया जाता है। कंपाइलर ऑप्टिमाइज़ेशन के कारण, &lt;code>std::unique_ptr&lt;/code> के माध्यम से एक्सेस करने पर कच्चे पॉइंटर के समान असेंबली कोड उत्पन्न होता है।&lt;/p>
&lt;h3 id="22-सवमतव-क-सथनतरण-और-stdmove">2.2 स्वामित्व का स्थानांतरण और &lt;code>std::move&lt;/code>
&lt;/h3>&lt;p>विशेष स्वामित्व होने के कारण, &lt;code>std::unique_ptr&lt;/code> को कॉपी नहीं किया जा सकता (कॉपी कंस्ट्रक्टर और कॉपी असाइनमेंट ऑपरेटर &lt;code>delete&lt;/code> कर दिए गए हैं)। स्वामित्व को दूसरे &lt;code>unique_ptr&lt;/code> में स्थानांतरित करने के लिए, &lt;code>std::move&lt;/code> का उपयोग करके मूव सेमांटिक्स (Move Semantics) का उपयोग किया जाता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;memory&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">Resource&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Resource&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Resource acquired&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">~&lt;/span>&lt;span class="n">Resource&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Resource destroyed&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">do_something&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Doing something&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">process_resource&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Resource&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">ptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ptr&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">do_something&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// स्कोप से बाहर निकलने पर ptr नष्ट हो जाता है, और Resource भी मुक्त हो जाता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Resource&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">my_ptr&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_unique&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Resource&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// process_resource(my_ptr); // त्रुटि: कॉपी नहीं किया जा सकता
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">process_resource&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">move&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">my_ptr&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// स्वामित्व का स्थानांतरण
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">my_ptr&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;my_ptr is now empty.&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>नीचे दिया गया Mermaid आरेख &lt;code>std::move&lt;/code> का उपयोग करके स्वामित्व के स्थानांतरण की अवधारणा को दर्शाता है।&lt;/p>
&lt;div class="mermaid">graph LR
subgraph "std::move से पहले"
A["unique_ptr (ptr1)"] -->|"स्वामित्व"| B["हीप मेमोरी (ऑब्जेक्ट)"]
end
subgraph "std::move के बाद"
C["unique_ptr (ptr1)"] -.->|"खाली (nullptr)"| D["nullptr"]
E["unique_ptr (ptr2)"] -->|"स्वामित्व"| F["हीप मेमोरी (ऑब्जेक्ट)"]
end&lt;/div>
&lt;h3 id="23-कसटम-डलटर-custom-deleter-क-करयनवयन">2.3 कस्टम डिलीटर (Custom Deleter) का कार्यान्वयन
&lt;/h3>&lt;p>C भाषा के लिगेसी API (जैसे &lt;code>FILE*&lt;/code> या सॉकेट) को रैप करते समय, मेमोरी को मुक्त करने के लिए &lt;code>delete&lt;/code> के अलावा अन्य कार्यों (जैसे &lt;code>fclose&lt;/code>) को कॉल करना आवश्यक हो सकता है। &lt;code>std::unique_ptr&lt;/code> के दूसरे टेम्प्लेट आर्गुमेंट के रूप में कस्टम डिलीटर निर्दिष्ट किया जा सकता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;cstdio&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;memory&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// कस्टम डिलीटर के लिए फनक्टर (Functor)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">struct&lt;/span> &lt;span class="nc">FileDeleter&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">void&lt;/span> &lt;span class="nf">operator&lt;/span>&lt;span class="p">()(&lt;/span>&lt;span class="n">FILE&lt;/span>&lt;span class="o">*&lt;/span> &lt;span class="n">fp&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">fp&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Closing file.&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">fclose&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">fp&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="n">UniqueFile&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">FILE&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">FileDeleter&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">UniqueFile&lt;/span> &lt;span class="n">file&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">fopen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;test.txt&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;w&amp;#34;&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">file&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">fputs&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Hello, Smart Pointers!&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">file&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// स्कोप समाप्त होने पर FileDeleter कॉल किया जाता है और fclose हो जाता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>यदि कस्टम डिलीटर के रूप में फ़ंक्शन पॉइंटर या लैम्ब्डा एक्सप्रेशन का उपयोग किया जाता है, तो &lt;code>unique_ptr&lt;/code> का आकार बढ़ सकता है, लेकिन जैसा कि ऊपर दिखाया गया है, स्टेटलेस फ़ंक्शन ऑब्जेक्ट (Functor) का उपयोग करने से C++ के &lt;strong>EBCO (Empty Base Class Optimization)&lt;/strong> या C++20 के &lt;code>[[no_unique_address]]&lt;/code> के कारण इसका आकार कच्चे पॉइंटर से अधिक नहीं बढ़ता है (शून्य ओवरहेड बना रहता है)।&lt;/p>
&lt;h2 id="3-stdshared_ptr-सझ-सवमतव-shared-ownership-और-कटरल-बलक">3. &lt;code>std::shared_ptr&lt;/code>: साझा स्वामित्व (Shared Ownership) और कंट्रोल ब्लॉक
&lt;/h2>&lt;p>&lt;code>std::shared_ptr&lt;/code> एक स्मार्ट पॉइंटर है जिसका उपयोग कई पॉइंटर्स द्वारा एक ही ऑब्जेक्ट के स्वामित्व को साझा करने के लिए किया जाता है। जब अंतिम &lt;code>shared_ptr&lt;/code> नष्ट हो जाता है, तो इसके द्वारा प्रबंधित ऑब्जेक्ट मुक्त हो जाता है।&lt;/p>
&lt;h3 id="31-आतरक-आरकटकचर-कटरल-बलक">3.1 आंतरिक आर्किटेक्चर: कंट्रोल ब्लॉक
&lt;/h3>&lt;p>&lt;code>std::shared_ptr&lt;/code> प्रबंधित ऑब्जेक्ट के पॉइंटर के अलावा, हीप पर &lt;strong>कंट्रोल ब्लॉक (Control Block)&lt;/strong> नामक मेटाडेटा आवंटित करता है और उसे साझा करता है। कंट्रोल ब्लॉक में निम्नलिखित जानकारी शामिल होती है:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Strong Count (मजबूत संदर्भ गणना)&lt;/strong>: ऑब्जेक्ट का स्वामित्व रखने वाले &lt;code>shared_ptr&lt;/code> की संख्या। जब यह 0 हो जाता है, तो ऑब्जेक्ट नष्ट हो जाता है।&lt;/li>
&lt;li>&lt;strong>Weak Count (कमजोर संदर्भ गणना)&lt;/strong>: ऑब्जेक्ट की निगरानी करने वाले &lt;code>weak_ptr&lt;/code> की संख्या। जब Strong Count और Weak Count दोनों 0 हो जाते हैं, तो कंट्रोल ब्लॉक स्वयं मुक्त हो जाता है।&lt;/li>
&lt;li>&lt;strong>कस्टम डिलीटर और एलोकेटर&lt;/strong> (यदि निर्दिष्ट हो)।&lt;/li>
&lt;/ol>
&lt;div class="mermaid">graph TD
A["std::shared_ptr&lt;T> (sp1)"] -->|"T की ओर पॉइंटर"| B["प्रबंधित ऑब्जेक्ट (T)"]
A -->|"कंट्रोल ब्लॉक की ओर पॉइंटर"| C["कंट्रोल ब्लॉक"]
D["std::shared_ptr&lt;T> (sp2)"] -->|"T की ओर पॉइंटर"| B
D -->|"कंट्रोल ब्लॉक की ओर पॉइंटर"| C
C -->|"हटाता है (Deletes)"| B
C -.->|"Strong Count: 2"| E["Strong Count"]
C -.->|"Weak Count: 0"| F["Weak Count"]
C -.->|"कस्टम डिलीटर"| G["डिलीटर"]&lt;/div>
&lt;p>इस कारण से, &lt;code>std::shared_ptr&lt;/code> ऑब्जेक्ट का आकार आमतौर पर कच्चे पॉइंटर से दोगुना (ऑब्जेक्ट की ओर पॉइंटर और कंट्रोल ब्लॉक की ओर पॉइंटर) होता है।&lt;/p>
&lt;h3 id="32-परदरशन-और-एटमक-ऑपरशस-atomic-operations">3.2 प्रदर्शन और एटॉमिक ऑपरेशंस (Atomic Operations)
&lt;/h3>&lt;p>कंट्रोल ब्लॉक के भीतर संदर्भ गणना (reference count) को &lt;strong>एटॉमिक ऑपरेशंस (Atomic Operations)&lt;/strong> के रूप में लागू किया जाता है, ताकि मल्टीथ्रेडेड वातावरण में भी इसे सुरक्षित रूप से बढ़ाया या घटाया जा सके।&lt;/p>
&lt;p>x86/x64 आर्किटेक्चर में, संदर्भ गणना को बढ़ाने या घटाने के लिए &lt;code>lock xadd&lt;/code> जैसे एटॉमिक निर्देशों का उपयोग किया जाता है। इसमें सामान्य पूर्णांक जोड़ (integer addition) की तुलना में दर्जनों साइकिलों का ओवरहेड होता है। इसलिए, यदि &lt;code>shared_ptr&lt;/code> को फ़ंक्शन में मान द्वारा (by value) पास किया जाता है, तो प्रत्येक कॉपी पर एटॉमिक इंक्रीमेंट और डिक्रीमेंट होता है, जिससे प्रदर्शन में कमी आती है।&lt;/p>
&lt;p>&lt;strong>सर्वोत्तम अभ्यास (Best Practice)&lt;/strong>: &lt;code>shared_ptr&lt;/code> को फ़ंक्शन में पास करते समय, जब तक कि स्वामित्व साझा करना आवश्यक न हो, इसे &lt;code>const std::shared_ptr&amp;lt;T&amp;gt;&amp;amp;&lt;/code> (const संदर्भ) के रूप में पास करना चाहिए, या कच्चा पॉइंटर/संदर्भ (raw pointer/reference) पास करना चाहिए।&lt;/p>
&lt;h3 id="33-stdmake_shared-vs-new">3.3 &lt;code>std::make_shared&lt;/code> vs &lt;code>new&lt;/code>
&lt;/h3>&lt;p>&lt;code>shared_ptr&lt;/code> बनाते समय, जहाँ तक संभव हो &lt;code>std::make_shared&lt;/code> का उपयोग करना चाहिए। इसके दो प्रमुख कारण हैं:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>मेमोरी आवंटन का अनुकूलन&lt;/strong>:
&lt;code>new&lt;/code> का उपयोग करने पर, ऑब्जेक्ट और कंट्रोल ब्लॉक के लिए हीप आवंटन (heap allocation) दो बार होता है। &lt;code>std::make_shared&lt;/code> का उपयोग करने पर, दोनों को समाहित करने वाला एक बड़ा मेमोरी ब्लॉक एक ही हीप आवंटन में सुरक्षित किया जा सकता है, जिससे कैश दक्षता (cache efficiency) भी बढ़ती है।&lt;/li>
&lt;li>&lt;strong>अपवाद सुरक्षा (Exception Safety)&lt;/strong>:
C++17 से पहले के मानकों में, फ़ंक्शन के तर्कों (arguments) के मूल्यांकन का क्रम अनिर्दिष्ट (unspecified) था, इसलिए &lt;code>new&lt;/code> द्वारा आवंटित पॉइंटर को &lt;code>shared_ptr&lt;/code> के कंस्ट्रक्टर में पास करने से पहले यदि अन्य तर्कों के मूल्यांकन के दौरान कोई अपवाद आता, तो मेमोरी लीक का जोखिम होता था। &lt;code>make_shared&lt;/code> इस समस्या से पूरी तरह बचाता है।&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// बचने योग्य तरीका (2 बार मेमोरी आवंटन)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">shared_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">MyClass&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">ptr1&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span> &lt;span class="n">MyClass&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// अनुशंसित तरीका (1 बार मेमोरी आवंटन)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">shared_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">MyClass&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">ptr2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_shared&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">MyClass&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="4-stdweak_ptr-सरकलर-रफरस-circular-references-क-समधन-और-नगरन">4. &lt;code>std::weak_ptr&lt;/code>: सर्कुलर रेफरेंस (Circular References) का समाधान और निगरानी
&lt;/h2>&lt;p>साझा स्वामित्व की एक बड़ी कमजोरी &amp;ldquo;सर्कुलर रेफरेंस (Circular References)&amp;rdquo; है। यदि ऑब्जेक्ट A और ऑब्जेक्ट B एक-दूसरे को &lt;code>shared_ptr&lt;/code> द्वारा इंगित कर रहे हैं, तो प्रत्येक का Strong Count कम से कम 1 पर बना रहता है, और प्रोग्राम समाप्त होने तक यह कभी 0 नहीं होता, जिससे मेमोरी लीक होती है।&lt;/p>
&lt;div class="mermaid">graph TD
subgraph "सर्कुलर रेफरेंस (Memory Leak)"
A["ऑब्जेक्ट A"] -->|"shared_ptr (Strong=1)"| B["ऑब्जेक्ट B"]
B -->|"shared_ptr (Strong=1)"| A
end&lt;/div>
&lt;h3 id="41-stdweak_ptr-दवर-चकर-cycle-क-तडन">4.1 &lt;code>std::weak_ptr&lt;/code> द्वारा चक्र (Cycle) को तोड़ना
&lt;/h3>&lt;p>इस समस्या का समाधान &lt;code>std::weak_ptr&lt;/code> है। &lt;code>weak_ptr&lt;/code> को &lt;code>shared_ptr&lt;/code> से बनाया जाता है और यह ऑब्जेक्ट को संदर्भित करता है, लेकिन &lt;strong>यह Strong Count को नहीं बढ़ाता है&lt;/strong>। इसके बजाय, यह Weak Count को बढ़ाता है। इससे स्वामित्व के बिना ऑब्जेक्ट की &amp;ldquo;निगरानी&amp;rdquo; की जा सकती है।&lt;/p>
&lt;div class="mermaid">graph TD
subgraph "सर्कुलर रेफरेंस को तोड़ना"
C["ऑब्जेक्ट A"] -->|"shared_ptr (Strong=1)"| D["ऑब्जेक्ट B"]
D -.->|"weak_ptr (Weak=1)"| C
end&lt;/div>
&lt;h3 id="42-lock-मथड-क-मधयम-स-सरकषत-एकसस">4.2 &lt;code>lock()&lt;/code> मेथड के माध्यम से सुरक्षित एक्सेस
&lt;/h3>&lt;p>&lt;code>weak_ptr&lt;/code> के पास सीधे ऑब्जेक्ट तक पहुँचने वाले ऑपरेटर (&lt;code>-&amp;gt;&lt;/code> या &lt;code>*&lt;/code>) नहीं होते हैं। ऐसा इसलिए है क्योंकि लक्षित ऑब्जेक्ट के नष्ट होने की संभावना हो सकती है। इसे सुरक्षित रूप से एक्सेस करने के लिए, &lt;code>lock()&lt;/code> मेथड को कॉल करके अस्थायी रूप से &lt;code>shared_ptr&lt;/code> प्राप्त किया जाता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;memory&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">Node&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">public&lt;/span>&lt;span class="o">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span> &lt;span class="n">name&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">shared_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Node&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">next&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">weak_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Node&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">prev&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// सर्कुलर रेफरेंस को रोकने के लिए weak_ptr का उपयोग
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Node&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">string&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">name&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Created &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">name&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">~&lt;/span>&lt;span class="n">Node&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Destroyed &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">name&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">nodeA&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_shared&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Node&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;A&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">nodeB&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_shared&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Node&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;B&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">nodeA&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">next&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nodeB&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">nodeB&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">prev&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nodeA&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// weak_ptr से shared_ptr प्राप्त करके एक्सेस करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">auto&lt;/span> &lt;span class="n">locked_prev&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nodeB&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">prev&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">lock&lt;/span>&lt;span class="p">())&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Node B&amp;#39;s prev is &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">locked_prev&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">name&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Node B&amp;#39;s prev is already destroyed.&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// nodeA और nodeB उचित रूप से नष्ट हो जाएंगे
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="5-मलटथरडड-वतवरण-म-सझ-सवमतव-क-समए">5. मल्टीथ्रेडेड वातावरण में साझा स्वामित्व की सीमाएँ
&lt;/h2>&lt;p>&lt;code>shared_ptr&lt;/code> की थ्रेड-सुरक्षा (thread safety) के बारे में अक्सर गलतफहमी होती है। &amp;ldquo;कंट्रोल ब्लॉक में संदर्भ गणना (reference count) का अपडेट थ्रेड-सेफ होता है&amp;rdquo;, लेकिन &amp;ldquo;&lt;code>shared_ptr&lt;/code> ऑब्जेक्ट को स्वयं पढ़ना या लिखना थ्रेड-सेफ नहीं होता है&amp;rdquo;।&lt;/p>
&lt;ul>
&lt;li>&lt;strong>सुरक्षित संचालन&lt;/strong>: कई थ्रेड्स, &lt;em>अपने स्वयं के&lt;/em> &lt;code>shared_ptr&lt;/code> इंस्टेंस (जो समान कंट्रोल ब्लॉक साझा करते हैं) को पढ़ते या लिखते हैं।&lt;/li>
&lt;li>&lt;strong>डेटा रेस (खतरा)&lt;/strong>: कई थ्रेड्स, &lt;em>बिल्कुल एक ही&lt;/em> &lt;code>shared_ptr&lt;/code> इंस्टेंस पर एक साथ पढ़ते या लिखते हैं।&lt;/li>
&lt;/ul>
&lt;p>यदि एक ही इंस्टेंस को कई थ्रेड्स के बीच साझा करने की आवश्यकता है, तो &lt;code>std::atomic&amp;lt;std::shared_ptr&amp;lt;T&amp;gt;&amp;gt;&lt;/code> (C++20) का उपयोग किया जाना चाहिए, या इसे म्यूटेक्स (&lt;code>std::mutex&lt;/code>) के साथ सुरक्षित किया जाना चाहिए।&lt;/p>
&lt;h2 id="6-सदरभ-गणन-क-गणतय-सतरकरण">6. संदर्भ गणना का गणितीय सूत्रीकरण
&lt;/h2>&lt;p>कंट्रोल ब्लॉक में जीवनचक्र अवस्था संक्रमण (lifecycle state transition) को गणितीय रूप में निम्न प्रकार से व्यक्त किया जा सकता है:
मान लें कि समय $t$ पर Strong Count $S(t)$ है और Weak Count $W(t)$ है।&lt;/p>
&lt;p>प्रारंभिक अवस्था (&lt;code>make_shared&lt;/code> के तुरंत बाद):
&lt;/p>
$$ S(0) = 1, \quad W(0) = 0 $$
&lt;p>कॉपी (&lt;code>shared_ptr&lt;/code> का प्रतिरूपण) होने पर:
&lt;/p>
$$ S(t_{next}) = S(t) + 1 $$
&lt;p>प्रबंधित ऑब्जेक्ट (Managed Object) के नष्ट होने की स्थिति:
&lt;/p>
$$ \lim_{t \to t_d} S(t) = 0 $$
&lt;p>कंट्रोल ब्लॉक (Control Block) स्वयं के मेमोरी से मुक्त होने की स्थिति:
&lt;/p>
$$ S(t) = 0 \quad \land \quad W(t) = 0 $$
&lt;p>
अर्थात,
&lt;/p>
$$ S(t) + W(t) = 0 $$
&lt;p>जैसा कि यह सूत्र दर्शाता है, जब तक &lt;code>weak_ptr&lt;/code> मौजूद है ($W(t) > 0$), प्रबंधित ऑब्जेक्ट के नष्ट होने के बाद भी कंट्रोल ब्लॉक के लिए छोटी मेमोरी स्पेस सुरक्षित रहती है। यह &lt;code>make_shared&lt;/code> का एकमात्र नुकसान हो सकता है (चूंकि प्रबंधित ऑब्जेक्ट की मेमोरी और कंट्रोल ब्लॉक एक साथ जुड़े होते हैं, यदि कोई कमजोर संदर्भ बचा रहता है, तो प्रबंधित ऑब्जेक्ट का विशाल मेमोरी स्थान भी सिस्टम को वापस नहीं किया जाता है), लेकिन आमतौर पर &lt;code>make_shared&lt;/code> का प्रदर्शन लाभ इन कमियों से कहीं अधिक होता है।&lt;/p>
&lt;h2 id="7-नषकरष">7. निष्कर्ष
&lt;/h2>&lt;p>मॉडर्न C++ में मेमोरी प्रबंधन अब मैन्युअल रूप से &lt;code>new&lt;/code>/&lt;code>delete&lt;/code> को प्रबंधित करने का युग नहीं है।&lt;/p>
&lt;ol>
&lt;li>डिफ़ॉल्ट रूप से हमेशा &lt;strong>&lt;code>std::unique_ptr&lt;/code>&lt;/strong> का उपयोग करें, और शून्य ओवरहेड का लाभ उठाते हुए स्पष्ट स्वामित्व को डिज़ाइन में शामिल करें।&lt;/li>
&lt;li>केवल तभी &lt;strong>&lt;code>std::shared_ptr&lt;/code>&lt;/strong> का उपयोग करें जब आपको वास्तव में कई मालिकों के बीच जीवनचक्र साझा करने की आवश्यकता हो, और इसे बनाने के लिए &lt;code>std::make_shared&lt;/code> का उपयोग करें।&lt;/li>
&lt;li>डेटा संरचनाओं या ऑब्जर्वर पैटर्न को लागू करने में जहां साझा करने का चक्र (सर्कुलर रेफरेंस) उत्पन्न हो सकता है, वहां मेमोरी लीक को रोकने के लिए &lt;strong>&lt;code>std::weak_ptr&lt;/code>&lt;/strong> का लाभ उठाएं।&lt;/li>
&lt;/ol>
&lt;p>स्मार्ट पॉइंटर्स को गहराई से समझने और उनका उचित स्थान पर उपयोग करने से, C++ के प्रदर्शन से समझौता किए बिना, सुरक्षित और मजबूत सॉफ्टवेयर आर्किटेक्चर का निर्माण संभव हो जाता है。&lt;/p></description></item></channel></rss>