<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Pointers on kenji.blog</title><link>http://kenji.blog/hi/tags/pointers/</link><description>Recent content in Pointers on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>hi</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 04:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/hi/tags/pointers/index.xml" rel="self" type="application/rss+xml"/><item><title>C++ पॉइंटर्स के साथ Rust के "स्वामित्व" और "उधार" की तुलना और व्याख्या</title><link>http://kenji.blog/hi/p/rust-ownership-borrowing-cpp-pointer-comparison/</link><pubDate>Sat, 12 Sep 2026 04:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/rust-ownership-borrowing-cpp-pointer-comparison/</guid><description>&lt;img src="http://kenji.blog/p/rust-ownership-borrowing-cpp-pointer-comparison/img/eyecatch.jpg" alt="Featured image of post C++ पॉइंटर्स के साथ Rust के "स्वामित्व" और "उधार" की तुलना और व्याख्या" />&lt;p>आधुनिक सिस्टम प्रोग्रामिंग में, प्रदर्शन और मेमोरी सुरक्षा को संतुलित करना एक शाश्वत चुनौती है। C++ लंबे समय से इस क्षेत्र का राजा रहा है, लेकिन हाल के वर्षों में Rust इसकी स्थिति के लिए खतरा बन रहा है। Rust की सबसे बड़ी विशेषता &amp;ldquo;स्वामित्व&amp;rdquo; (Ownership) और &amp;ldquo;उधार&amp;rdquo; (Borrowing) की अवधारणा है, जो बिना कचरा संग्रहण (Garbage Collection या GC) के संकलन के समय (compile time) मेमोरी सुरक्षा की गारंटी देती है।&lt;/p>
&lt;p>इस लेख में, हम C++ के पॉइंटर्स (raw pointers, &lt;code>std::unique_ptr&lt;/code>, &lt;code>std::shared_ptr&lt;/code>) और Rust के स्वामित्व मॉडल की विस्तार से तुलना करेंगे। हम कोड उदाहरणों और आरेखों के साथ गहराई से बताएंगे कि Rust का कंपाइलर (बरो चेकर) यूज़-आफ्टर-फ्री (Use-After-Free) और डेटा रेस (Data Race) को कैसे रोकता है।&lt;/p>
&lt;h2 id="1-ममर-परबधन-क-मल-ततव-सटक-और-हप">1. मेमोरी प्रबंधन के मूल तत्व: स्टैक और हीप
&lt;/h2>&lt;p>मेमोरी प्रबंधन की मूल बातें समझने के लिए, आइए पहले देखें कि कोई प्रोग्राम मेमोरी का उपयोग कैसे करता है। मेमोरी क्षेत्र को मोटे तौर पर &amp;ldquo;स्टैक&amp;rdquo; (Stack) और &amp;ldquo;हीप&amp;rdquo; (Heap) में वर्गीकृत किया जाता है।&lt;/p>
&lt;h3 id="सटक-stack">स्टैक (Stack)
&lt;/h3>&lt;p>यह वह क्षेत्र है जहाँ फ़ंक्शन कॉल के दौरान स्थानीय चर आदि जमा किए जाते हैं। इसकी LIFO (लास्ट-इन, फर्स्ट-आउट) संरचना है, और मेमोरी आवंटन/मुक्ति (allocation/deallocation) बहुत तेज़ है। इसमें केवल वह डेटा रखा जाता है जिसका आकार संकलन के समय (compile time) निर्धारित किया जा सकता है।&lt;/p>
&lt;h3 id="हप-heap">हीप (Heap)
&lt;/h3>&lt;p>इसमें वह डेटा रखा जाता है जिसका आकार रनटाइम पर गतिशील रूप से निर्धारित होता है, या वह डेटा जिसे फ़ंक्शन के दायरे (scope) से परे जीवित रहने की आवश्यकता होती है। इसे पॉइंटर्स (या संदर्भों) के माध्यम से एक्सेस किया जाता है।&lt;/p>
&lt;p>बिना कचरा संग्रहण वाले C++ और Rust में, हीप मेमोरी प्रबंधन की लागत को निम्न सूत्र के रूप में मॉडल किया जा सकता है। मान लीजिए कि वस्तुओं की कुल संख्या $N$ है, आवंटन के लिए औसत समय $T_{alloc}$ है, और मुक्ति के लिए औसत समय $T_{dealloc}$ है। तब कुल मेमोरी प्रबंधन लागत $C_{memory}$ होगी:&lt;/p>
$$ C_{memory} = \sum_{i=1}^{N} (T_{alloc, i} + T_{dealloc, i}) + O_{sync} $$
&lt;p>यहाँ, $O_{sync}$ मल्टी-थ्रेडेड वातावरण में पारस्परिक अपवर्जन (mutual exclusion जैसे कि म्यूटेक्स या परमाणु संचालन) का ओवरहेड है। चूंकि Rust संकलन के समय मेमोरी मुक्ति का समय निर्धारित करता है, यह रनटाइम पर कचरा संग्रहण के कारण थ्रूपुट में कमी (Stop-The-World) को शून्य कर देता है, और $T_{dealloc}$ को विश्वसनीय और सुरक्षित समय पर निष्पादित करता है।&lt;/p>
&lt;div class="mermaid">graph TD
A["प्रोग्राम मेमोरी"] --> B["स्टैक (तेज़, निश्चित आकार)"]
A --> C["हीप (गतिशील, धीमा)"]
B --> D["स्थानीय चर"]
B --> E["पॉइंटर्स/संदर्भ"]
C --> F["गतिशील रूप से आवंटित डेटा"]
E -.->|"इंगित करता है"| F&lt;/div>
&lt;h2 id="2-c-पइटरस-सवततरत-और-खतर-क-बच-क-वयपर">2. C++ पॉइंटर्स: स्वतंत्रता और खतरे के बीच का व्यापार
&lt;/h2>&lt;p>आइए C++ में मेमोरी प्रबंधन के विकास पर एक नज़र डालें।&lt;/p>
&lt;h3 id="र-पइटरस-raw-pointers-क-यग-और-समसयए">रॉ पॉइंटर्स (Raw Pointers) का युग और समस्याएं
&lt;/h3>&lt;p>C भाषा से विरासत में मिले रॉ पॉइंटर्स (&lt;code>*&lt;/code>) परम स्वतंत्रता प्रदान करते हैं, लेकिन साथ ही वे निम्नलिखित गंभीर बग्स का कारण भी बनते हैं:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>मेमोरी लीक (Memory Leak)&lt;/strong>: &lt;code>new&lt;/code> के साथ आवंटित मेमोरी को &lt;code>delete&lt;/code> करना भूल जाना।&lt;/li>
&lt;li>&lt;strong>डैंगलिंग पॉइंटर (Dangling Pointer)&lt;/strong>: मेमोरी मुक्त होने (&lt;code>delete&lt;/code>) के बाद पॉइंटर को एक्सेस करना।&lt;/li>
&lt;li>&lt;strong>डबल फ्री (Double Free)&lt;/strong>: एक ही मेमोरी क्षेत्र को दो बार &lt;code>delete&lt;/code> करना।&lt;/li>
&lt;/ul>
&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;/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">// C++: रॉ पॉइंटर के कारण होने वाली समस्या का उदाहरण
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kt">void&lt;/span> &lt;span class="nf">rawPointerExample&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">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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// गलती से फिर से एक्सेस करना (Use-After-Free / Dangling Pointer)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// C++ कंपाइलर इसे संकलन त्रुटि (compile error) नहीं बना सकता
&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">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="o">*&lt;/span>&lt;span class="n">ptr&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// अपरिभाषित व्यवहार (Undefined Behavior)
&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;h3 id="raii-और-समरट-पइटरस-क-उदय-c11-और-उसक-बद">RAII और स्मार्ट पॉइंटर्स का उदय (C++11 और उसके बाद)
&lt;/h3>&lt;p>C++11 के बाद से, RAII (Resource Acquisition Is Initialization) अवधारणा पर आधारित स्मार्ट पॉइंटर्स को मानकीकृत किया गया, और रॉ पॉइंटर्स के सीधे उपयोग को हतोत्साहित किया गया।&lt;/p>
&lt;h4 id="stdunique_ptr">&lt;code>std::unique_ptr&lt;/code>
&lt;/h4>&lt;p>यह एक पॉइंटर है जो व्यक्त करता है कि स्वामित्व एकल है। जब यह दायरे (scope) से बाहर हो जाता है, तो मेमोरी स्वचालित रूप से मुक्त हो जाती है। इसे कॉपी नहीं किया जा सकता है; स्वामित्व को केवल &amp;ldquo;स्थानांतरित&amp;rdquo; (move) किया जा सकता है (&lt;code>std::move&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;/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">// C++: std::unique_ptr
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&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">#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">&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">uniquePtrExample&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="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">p1&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="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">42&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// std::unique_ptr&amp;lt;int&amp;gt; p2 = p1; // संकलन त्रुटि (कॉपी नहीं किया जा सकता)
&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">unique_ptr&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">p3&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">move&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">p1&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="c1">// C++ की कमजोरी: स्थानांतरित होने के बाद p1 nullptr हो जाता है, लेकिन एक्सेस स्वयं संकलित हो सकता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// जो रनटाइम पर क्रैश (segmentation fault) का कारण बनेगा
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// std::cout &amp;lt;&amp;lt; *p1 &amp;lt;&amp;lt; std::endl;
&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;h4 id="stdshared_ptr">&lt;code>std::shared_ptr&lt;/code>
&lt;/h4>&lt;p>यह एक पॉइंटर है जो कई पॉइंटर्स को एक ही ऑब्जेक्ट साझा करने की अनुमति देता है। यह संदर्भ गणना (Reference Counting) का उपयोग करता है, और गिनती शून्य होने पर मेमोरी को मुक्त करता है। चूंकि इसके लिए परमाणु वृद्धि/कमी संचालन की आवश्यकता होती है, इसलिए इसमें थोड़ा प्रदर्शन ओवरहेड (पहले उल्लेखित $O_{sync}$ के समतुल्य) होता है।&lt;/p>
&lt;h2 id="3-rust-क-सवमतव-ownership-एक-आदरश-बदलव-paradigm-shift">3. Rust का स्वामित्व (Ownership): एक आदर्श बदलाव (Paradigm Shift)
&lt;/h2>&lt;p>Rust ने C++ के &lt;code>std::unique_ptr&lt;/code> की अवधारणा को अपनी भाषा विनिर्देशन के मूल में रखा है और इसका एक सख्त &amp;ldquo;स्वामित्व मॉडल&amp;rdquo; है।&lt;/p>
&lt;h3 id="सवमतव-क-3-नयम">स्वामित्व के 3 नियम
&lt;/h3>&lt;p>Rust का स्वामित्व सिस्टम निम्नलिखित तीन अत्यंत सरल नियमों पर आधारित है:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Rust में प्रत्येक मूल्य (value) का एक चर (variable) होता है जिसे उसका स्वामी (owner) कहा जाता है।&lt;/strong>&lt;/li>
&lt;li>&lt;strong>एक समय में केवल एक ही स्वामी हो सकता है।&lt;/strong>&lt;/li>
&lt;li>&lt;strong>जब स्वामी दायरे (scope) से बाहर हो जाता है, मूल्य नष्ट हो जाता है।&lt;/strong>&lt;/li>
&lt;/ol>
&lt;p>Rust में डिफ़ॉल्ट रूप से संसाधनों को &amp;ldquo;स्थानांतरित&amp;rdquo; (move) किया जाता है। C++ के &lt;code>std::move&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Rust: स्वामित्व का स्थानांतरण (Move)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">s1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">String&lt;/span>::&lt;span class="n">from&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;hello&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w"> &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 class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">s2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">s1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// स्वामित्व s1 से s2 में स्थानांतरित (move) हो जाता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c1">// C++ के साथ सबसे बड़ा अंतर: स्थानांतरित चर तक पहुंच &amp;#34;संकलन त्रुटि&amp;#34; (compile error) बन जाती है!
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// println!(&amp;#34;{}, world!&amp;#34;, s1); // संकलन त्रुटि: value borrowed here after move
&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 class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>यह सुविधा जो &amp;ldquo;स्थानांतरित चर तक पहुंच को संकलन समय पर अक्षम कर देती है&amp;rdquo;, उन कारणों में से एक है कि Rust C++ के &lt;code>std::unique_ptr&lt;/code> से अधिक सुरक्षित क्यों है।&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant S1 as "चर s1"
participant Heap as "हीप मेमोरी ('hello')"
participant S2 as "चर s2"
S1->>Heap: "आवंटित करता है और स्वामित्व रखता है"
Note over S1,S2: "let s2 = s1;"
S1--xHeap: "स्वामित्व खो देता है (अमान्य)"
S2->>Heap: "स्वामित्व ले लेता है"&lt;/div>
&lt;h2 id="4-उधर-borrowing-और-सदरभ-references">4. उधार (Borrowing) और संदर्भ (References)
&lt;/h2>&lt;p>यदि स्वामित्व हमेशा स्थानांतरित किया जाता है, तो हर बार फ़ंक्शन में मूल्य पास करने पर आपको स्वामित्व वापस लेना होगा, जो बहुत असुविधाजनक है। यहीं पर &amp;ldquo;उधार&amp;rdquo; (Borrowing) खेल में आता है। यह C++ पॉइंटर्स या संदर्भों के समतुल्य है।&lt;/p>
&lt;p>Rust में उधार दो प्रकार के होते हैं:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>अपरिवर्तनीय संदर्भ (Immutable Reference)&lt;/strong>: &lt;code>&amp;amp;T&lt;/code> (C++ के &lt;code>const T&amp;amp;&lt;/code> के समान)&lt;/li>
&lt;li>&lt;strong>परिवर्तनीय संदर्भ (Mutable Reference)&lt;/strong>: &lt;code>&amp;amp;mut T&lt;/code> (C++ के &lt;code>T&amp;amp;&lt;/code> के समान)&lt;/li>
&lt;/ul>
&lt;h3 id="बर-चकर-borrow-checker-क-कठर-नयम">बरो चेकर (Borrow Checker) के कठोर नियम
&lt;/h3>&lt;p>Rust के कंपाइलर में एक अंतर्निहित &amp;ldquo;बरो चेकर&amp;rdquo; होता है जो संदर्भों की वैधता की पुष्टि करता है। बरो चेकर निम्नलिखित सख्त नियमों को लागू करता है:&lt;/p>
&lt;blockquote>
&lt;p>किसी भी दायरे (scope) में, किसी भी समय, केवल निम्नलिखित में से एक मौजूद हो सकता है:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>एक परिवर्तनीय संदर्भ (&lt;code>&amp;amp;mut T&lt;/code>)&lt;/strong>&lt;/li>
&lt;li>&lt;strong>कई अपरिवर्तनीय संदर्भ (&lt;code>&amp;amp;T&lt;/code>)&lt;/strong>&lt;/li>
&lt;/ul>
&lt;/blockquote>
&lt;p>इसे &lt;strong>&amp;ldquo;मल्टीपल रीडर्स एक्सओआर सिंगल राइटर (MRSW)&amp;rdquo;&lt;/strong> सिद्धांत कहा जाता है। इसे गणितीय अनन्य OR (XOR) द्वारा दर्शाया जा सकता है। एक स्थिति $S$ के लिए, अपरिवर्तनीय संदर्भों की संख्या $N_r$ और परिवर्तनीय संदर्भों की संख्या $N_w$ को निम्नलिखित बाधा को पूरा करना होगा:&lt;/p>
$$ (N_r \ge 0 \land N_w = 0) \oplus (N_r = 0 \land N_w = 1) $$
&lt;p>इस नियम के माध्यम से, &lt;strong>डेटा रेस (Data Race) संकलन समय (compile time) पर पूरी तरह से समाप्त हो जाता है&lt;/strong>। डेटा रेस तब होता है जब: ① दो या दो से अधिक पॉइंटर्स एक ही डेटा तक एक साथ पहुंचते हैं, ② कम से कम एक लिख रहा होता है (write operation), और ③ कोई सिंक्रनाइज़ेशन तंत्र नहीं होता है। Rust संकलन समय पर स्थिति ② को नष्ट करके डेटा रेस को रोकता है।&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Rust: उधार नियम के उल्लंघन के कारण संकलन त्रुटि
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">s&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">String&lt;/span>::&lt;span class="n">from&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;hello&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">r1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">s&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// अपरिवर्तनीय उधार (OK)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">r2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">s&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// अपरिवर्तनीय उधार (OK)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// let r3 = &amp;amp;mut s; // त्रुटि! अपरिवर्तनीय उधार मौजूद होने पर परिवर्तनीय उधार नहीं बनाया जा सकता
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="fm">println!&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="si">{}&lt;/span>&lt;span class="s">, &lt;/span>&lt;span class="si">{}&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">r1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">r2&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="5-इटरटर-अमनयकरण-iterator-invalidation-क-रकथम">5. इटरेटर अमान्यकरण (Iterator Invalidation) की रोकथाम
&lt;/h2>&lt;p>बरो चेकर की शक्ति के सबसे ठोस उदाहरण के रूप में, आइए &amp;ldquo;इटरेटर अमान्यकरण&amp;rdquo; (Iterator Invalidation) नामक एक क्लासिक बग देखें।&lt;/p>
&lt;h3 id="c-म-इटरटर-अमनयकरण-रनटइम-करश">C++ में इटरेटर अमान्यकरण (रनटाइम क्रैश)
&lt;/h3>&lt;p>यदि आप लूप के दौरान C++ &lt;code>std::vector&lt;/code> को संशोधित करते हैं, तो इसके पीछे की मेमोरी फिर से आवंटित (Reallocation) हो सकती है, और संदर्भ एक डैंगलिंग पॉइंटर बन जाएगा।&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;/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">// C++: इटरेटर अमान्यकरण बग
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&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;vector&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="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">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">v&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&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">// वेक्टर के तत्व का संदर्भ प्राप्त करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">first&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">v&lt;/span>&lt;span class="p">[&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>&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="c1">// और पुराना क्षेत्र नष्ट हो सकता है)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">v&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&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">// first पहले से ही मुक्त मेमोरी को इंगित कर रहा हो सकता है! (अपरिभाषित व्यवहार)
&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">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;The first element is: &amp;#34;&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">first&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">endl&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="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;h3 id="rust-क-सकलन-समय-बचव">Rust का संकलन-समय बचाव
&lt;/h3>&lt;p>आइए ठीक इसी तर्क को Rust में लिखें।&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Rust: संकलन समय पर इटरेटर अमान्यकरण को रोकना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="fm">vec!&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">];&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &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 class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">first&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">];&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c1">// त्रुटि! जबकि `first` `v` को अपरिवर्तनीय रूप से उधार ले रहा है,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// हम `v.push` के लिए आवश्यक परिवर्तनीय उधार नहीं ले सकते।
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// v.push(4);
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="fm">println!&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;The first element is: &lt;/span>&lt;span class="si">{}&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">first&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस तरह, चूँकि Rust कंपाइलर स्तर पर &amp;ldquo;किसी मान को पढ़ते समय (अपरिवर्तनीय उधार) उसे बदलना (परिवर्तनीय उधार)&amp;rdquo; सख्त मना करता है, यूज़-आफ्टर-फ्री और इटरेटर अमान्यकरण जैसे घातक बग संकलन समय पर निश्चित रूप से पकड़े जाते हैं।&lt;/p>
&lt;div class="mermaid">graph LR
A["चर v (स्वामी)"] --> B["हीप ऐरे [1, 2, 3]"]
C["संदर्भ 'first' (&amp;v[0])"] -.->|"अपरिवर्तनीय उधार"| B
A -->|X "परिवर्तनीय उधार अस्वीकृत!"| D["v.push(4)"]
style C stroke:#00FF00,stroke-width:2px
style D stroke:#FF0000,stroke-width:2px&lt;/div>
&lt;h2 id="6-rust-म-सझ-सवमतव-rc-और-arc">6. Rust में साझा स्वामित्व: &lt;code>Rc&lt;/code> और &lt;code>Arc&lt;/code>
&lt;/h2>&lt;p>Rust साझा स्वामित्व (Shared Ownership) भी प्रदान करता है जो C++ के &lt;code>std::shared_ptr&lt;/code> के बराबर है, लेकिन प्रकारों को सिंगल-थ्रेडेड और मल्टी-थ्रेडेड उपयोग के लिए स्पष्ट रूप से अलग किया गया है।&lt;/p>
&lt;h3 id="सगल-थरडड-उपयग-क-लए-rct-reference-counted">सिंगल-थ्रेडेड उपयोग के लिए: &lt;code>Rc&amp;lt;T&amp;gt;&lt;/code> (Reference Counted)
&lt;/h3>&lt;p>&lt;code>Rc&amp;lt;T&amp;gt;&lt;/code> एक गैर-थ्रेड-सुरक्षित संदर्भ-गिने जाने वाला स्मार्ट पॉइंटर है। यह परमाणु (atomic) निर्देशों का उपयोग किए बिना गिनती बढ़ाता/घटाता है, जिससे यह एक थ्रेड के भीतर बहुत तेज़ हो जाता है। हालाँकि, यदि आप इसे दूसरे थ्रेड में भेजने का प्रयास करते हैं, तो एक संकलन त्रुटि होगी (क्योंकि यह &lt;code>Send&lt;/code> ट्रेट को लागू नहीं करता है)।&lt;/p>
&lt;h3 id="मलट-थरडड-उपयग-क-लए-arct-atomic-reference-counted">मल्टी-थ्रेडेड उपयोग के लिए: &lt;code>Arc&amp;lt;T&amp;gt;&lt;/code> (Atomic Reference Counted)
&lt;/h3>&lt;p>थ्रेड्स के बीच साझा करते समय, हम &lt;code>Arc&amp;lt;T&amp;gt;&lt;/code> का उपयोग करते हैं, जो परमाणु वृद्धि/कमी करता है। इसमें C++ के &lt;code>std::shared_ptr&lt;/code> के समान लागत होती है।&lt;/p>
&lt;p>इसके अलावा, C++ में, यदि कई थ्रेड एक साथ &lt;code>std::shared_ptr&lt;/code> द्वारा साझा किए गए चर में लिखते हैं, तो डेटा रेस होता है। इसे रोकने के लिए, आपको &lt;code>std::mutex&lt;/code> का सही ढंग से उपयोग करना होगा।&lt;/p>
&lt;p>दूसरी ओर, Rust में, आप अकेले &lt;code>Arc&amp;lt;T&amp;gt;&lt;/code> के साथ &lt;strong>आंतरिक डेटा को संशोधित नहीं कर सकते&lt;/strong> हैं। यदि संशोधन की आवश्यकता है, तो इसे म्यूटेक्स &lt;code>Mutex&amp;lt;T&amp;gt;&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;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-rust" data-lang="rust">&lt;span class="line">&lt;span class="cl">&lt;span class="k">use&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>::&lt;span class="n">sync&lt;/span>::&lt;span class="p">{&lt;/span>&lt;span class="n">Arc&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Mutex&lt;/span>&lt;span class="p">};&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">use&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">std&lt;/span>::&lt;span class="n">thread&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">fn&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &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 class="w"> &lt;/span>&lt;span class="c1">// C++ के std::shared_ptr&amp;lt;std::mutex&amp;gt; के समान है, लेकिन Mutex डेटा को समाहित करता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">counter&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Arc&lt;/span>::&lt;span class="n">new&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Mutex&lt;/span>::&lt;span class="n">new&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">handles&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="fm">vec!&lt;/span>&lt;span class="p">[];&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">_&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="o">..&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">counter_clone&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Arc&lt;/span>::&lt;span class="n">clone&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">counter&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">handle&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">thread&lt;/span>::&lt;span class="n">spawn&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">move&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">||&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c1">// lock() को कॉल करने पर ही आप आंतरिक परिवर्तनीय संदर्भ (&amp;amp;mut i32) प्राप्त कर सकते हैं
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">let&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">mut&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">num&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">counter_clone&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">lock&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="n">unwrap&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">num&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">+=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">});&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// RAII के कारण दायरे (scope) से बाहर निकलते ही लॉक स्वचालित रूप से जारी हो जाता है
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">handles&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">handle&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">for&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">handle&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">handles&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">handle&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">join&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="n">unwrap&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="fm">println!&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Result: &lt;/span>&lt;span class="si">{}&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="n">counter&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">lock&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="n">unwrap&lt;/span>&lt;span class="p">());&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>उल्लेखनीय बात यह है कि Rust का &lt;code>Mutex&amp;lt;T&amp;gt;&lt;/code> केवल एक लॉकिंग तंत्र नहीं है, बल्कि &lt;strong>&amp;ldquo;सुरक्षित किए जाने वाले डेटा को एक प्रकार (type) के रूप में समाहित करता है&amp;rdquo;&lt;/strong>। यह संकलन स्तर पर &amp;ldquo;लॉक प्राप्त करना भूल जाना और डेटा तक पहुंचना&amp;rdquo; जैसी गलतियों को पूरी तरह से रोकता है। जब तक आप लॉक (&lt;code>lock()&lt;/code>) प्राप्त नहीं करते हैं, तब तक आप आंतरिक डेटा तक पहुंचने के अधिकार (संदर्भ) प्राप्त नहीं कर सकते हैं।&lt;/p>
&lt;h2 id="नषकरष-कपइलर-दवर-परव-नरकषण-य-डवलपर-दवर-सवय-क-जममदर">निष्कर्ष: कंपाइलर द्वारा &amp;ldquo;पूर्व-निरीक्षण&amp;rdquo; या डेवलपर द्वारा &amp;ldquo;स्वयं की जिम्मेदारी&amp;rdquo;?
&lt;/h2>&lt;p>C++ पॉइंटर्स और स्मार्ट पॉइंटर्स डेवलपर्स को उच्च स्तर का नियंत्रण और प्रदर्शन प्रदान करते हैं, लेकिन उनका सही उपयोग डेवलपर्स के अनुशासन पर निर्भर करता है। RAII और &lt;code>std::unique_ptr&lt;/code> की शुरुआत ने C++ को नाटकीय रूप से सुरक्षित बना दिया है, लेकिन यह अभी भी &amp;ldquo;अपरिभाषित व्यवहार&amp;rdquo; (undefined behavior) जैसे कि मूव के बाद एक्सेस या इटरेटर अमान्यकरण को भाषा स्तर पर पूरी तरह से नहीं रोक सकता है।&lt;/p>
&lt;p>दूसरी ओर, Rust कंपाइलर में स्वामित्व (Ownership) और उधार (Borrowing) के नियमों को शामिल करके रनटाइम के बजाय &lt;strong>संकलन समय (compile time)&lt;/strong> पर इन त्रुटियों का पता लगाता है। &amp;ldquo;यदि यह संकलित होता है, तो यह मेमोरी सुरक्षित है&amp;rdquo; की यह मजबूत गारंटी सबसे बड़ा कारण है कि Rust सिस्टम प्रोग्रामिंग में तेजी से समर्थन प्राप्त कर रहा है।&lt;/p>
&lt;p>Rust के बरो चेकर से लड़ना (Fight the borrow checker) शुरुआती लोगों के लिए एक बड़ी बाधा हो सकती है, लेकिन यह केवल कंपाइलर द्वारा &amp;ldquo;पॉइंटर के जीवनकाल को ट्रैक करने&amp;rdquo; की जटिल गणना को सख्ती से करने के लिए है, जो मूल रूप से C++ प्रोग्रामर्स को अपने दिमाग में करना पड़ता था।&lt;/p>
&lt;p>C++ पॉइंटर्स की स्वतंत्रता और खतरों को समझने के बाद Rust सीखने से आपको स्वामित्व मॉडल के पीछे &amp;ldquo;यह डिज़ाइन क्यों चुना गया&amp;rdquo; के दर्शन को अधिक गहराई से समझने में मदद मिलेगी।&lt;/p>
&lt;hr>
&lt;p>&lt;em>यह लेख C++ और Rust के बीच मेमोरी प्रबंधन तकनीकों का तुलनात्मक अध्ययन है। हमें उम्मीद है कि यह प्रत्येक परियोजना की आवश्यकताओं के अनुसार उपयुक्त भाषा चुनने के लिए एक संदर्भ के रूप में कार्य करेगा।&lt;/em>&lt;/p></description></item></channel></rss>