vvint1
और vvint2
द्वारा ली गई मेमोरी में अपेक्षित अंतर (यदि कोई हो) क्या है? क्या हर बार push_back
होने पर vitest1
को एक नई मेमोरी स्थिति में कॉपी किया जाता है? क्या हर बार push_back
होने पर vitest2
को एक नई मेमोरी स्थिति में कॉपी किया जाता है?
typedef vector<int> vint_t;
typedef vector<vint_t> vvint_t;
size_t nvec = 2;
size_t nvvec = 3;
vvint_t vvint1(nvvec), vvint2(nvvec);
vint_t vitest2(nvec, 1);
for ( j = 0; j < nvvec; j++ ) {
vint_t vitest1(nvec, 2);
vvint1.push_back(vitest1);
vvint2.push_back(vitest2);
}
2 जवाब
दोनों vvint1
और vvint2
शुरू में nvvec = 3
डिफ़ॉल्ट-निर्मित सदस्यों (यानी int के खाली वैक्टर) के साथ बनाए गए हैं।
push_back
हमेशा या तो कॉपी करता है या चलता है, लेकिन इस मामले में आप प्रतिद्वंद्विता संदर्भों की आपूर्ति नहीं कर रहे हैं, इसलिए आपको प्रतियां मिलेंगी। उस पर अधिक जानकारी के लिए std::move
देखें।
आप दोनों वैक्टरों को समान संख्या में चीजें दबा रहे हैं। इसलिए vvint1
और vvint2
दोनों एक ही आकार के होंगे।
vvint1
और vvint2
मेमोरी आवश्यकताएं हैं:
- (स्टैक पर, उदाहरण में)
sizeof(vector<vector<int>>)
स्वयं वस्तुओं के लिए, जो समान है (vector
आमतौर पर आंतरिक प्रकार की परवाह किए बिना 2-3 पॉइंटर्स होते हैं); - (ढेर पर)
2 * nvvec * sizeof(vector<int>)
सामग्री के लिए (nvvec
शुरू में औरnvvec
push_back
-लूप में); फिर से,vvint1
औरvvint2
के लिए भी ऐसा ही है; - (ढेर पर) इन वैक्टर में संग्रहीत प्रत्येक वेक्टर की सामग्री। चूंकि वेक्टर मेमोरी साझा नहीं करते हैं, और आप उन्हें मूल्य के आधार पर स्टोर करते हैं,
nvec * nnvec * sizeof(int)
। फिर वही।
तो समग्र आवश्यकताएं समान हैं: sizeof(vector<vector<int>>) + nvvec * sizeof(vector<int>) + nvec * nnvec * sizeof(int)
सादा vector<int>
कम जगह लेगा क्योंकि आइटम 2 लागू नहीं होगा। लेकिन जो अधिक महत्वपूर्ण है वह यह है कि vvint_t
में, आंतरिक वैक्टर अलग-अलग लंबाई के हो सकते हैं, और किसी भी आंतरिक वेक्टर का आकार बदलना दूसरों को प्रभावित नहीं करता है। लेकिन यह जटिलता जोड़ता है, इसलिए जब तक आपको वास्तव में इसकी आवश्यकता न हो, फ्लैट वेक्टर का उपयोग करना और सूचकांक की गणना करना आसान है; इमेजिंग पुस्तकालय इसे इस तरह से करते हैं।
दूसरे भाग के संबंध में, दोनों vitest
s प्रत्येक push_back पर कॉपी किए गए हैं। लेकिन C++11 के बाद से, आप इसके बजाय स्थानांतरित करने के लिए vvint1.push_back(std::move(vitest1));
(या vvint1.emplace_back(std::move(vitest1));
) लिख सकते हैं। वैक्टर के लिए जिसका अर्थ है कि नव-निर्मित वेक्टर vitest1
सामग्री को कॉपी किए बिना उसका स्वामित्व लेता है (इसलिए vitest1
खाली हो जाता है)। यह स्मृति आवश्यकताओं को नहीं बदलता है, लेकिन आवंटन को कम करता है क्योंकि vitest
(निर्माण पर) द्वारा आवंटित स्थान को मुक्त होने के बजाय पुन: उपयोग किया जाएगा (विनाश पर, प्रत्येक पुनरावृत्ति के अंत में)।
2 * nvvec * sizeof(vector<int>)
? (दिया गया है कि यह nvvec
से शुरू होता है और push_back
s हैं)।
संबंधित सवाल
नए सवाल
c++
C ++ एक सामान्य-प्रयोजन प्रोग्रामिंग भाषा है। यह मूल रूप से C के विस्तार के रूप में डिज़ाइन किया गया था और इसमें एक समान सिंटैक्स है, लेकिन यह अब पूरी तरह से अलग भाषा है। C ++ कंपाइलर के साथ संकलित कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें। विशिष्ट मानक संशोधन [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] या [C ++ 23], आदि से संबंधित प्रश्नों के लिए संस्करण-विशिष्ट टैग का उपयोग करें। ।
vvint1
औरvvint2
एक जैसे होंगे। हर बार जब आपpush_pack
का उपयोग करते हैं तो दोनों वेक्टर को कॉपी करते हैं। FWIW, एक 2d-वेक्टर वह नहीं है जो आप चाहते हैं।int**
की तरह,std::vector<std::vector<int>>
में पंक्तियों के बीच डेटा स्थान नहीं है। निरंतरता की कमी प्रदर्शन में बाधा डाल सकती है। इसके बजाय, आपको क्या करना चाहिए एक वर्ग का उपयोग करके एक एसडी संरचना का अनुकरण करना और 2 डी इंडेक्स को 1 डी इंडेक्स में अनुवाद करने के लिए गणित का उपयोग करके 1 डी वेक्टर में सभी डेटा संग्रहीत करना।vint_t
औरvvint_t
को मिलाने वाला है और क्योंकि नाम इतने समान हैं कि इसका पता लगाना मुश्किल होगा।vvint_t vvint1(nvvec), vvint2(nvvec);
aaaaaaaahhh यह इतना अपठनीय कोड है।