2011-11-22 7 views
6

यह सुंदर दूर की कौड़ी है, लेकिन निम्न कोड "सुरक्षित" (यानी विभाजन गलती पैदा करने के लिए नहीं की गारंटी) है:std :: vector :: आरक्षित सुरक्षित के बाद कच्चे सूचक का उपयोग कर रहा है?

std::vector<int> vec(1); // Ensures that &vec[0] is valid 
vec.reserve(100); 
memset(&vec[0], 0x123, sizeof(int)*100); // Safe? 

मुझे लगता है कि यह बदसूरत है - मैं अगर यह तकनीकी रूप से सुरक्षित है पता करने के लिए केवल इच्छुक हूँ , सुंदर नहीं"। मुझे लगता है कि इसका एकमात्र उपयोग किसी दिए गए इंडेक्स से अधिक मूल्यों को अनदेखा कर सकता है।

नोट! How can I get the address of the buffer allocated by vector::reserve()? एक ही विषय को शामिल करता है, लेकिन मुझे अधिक दिलचस्पी है यदि यह सुरक्षित है और यदि ऐसा करने में समस्याएं हैं।

संपादित करें: मूल कोड गलत था, को memset के साथ बदल दिया गया।

+1

ठीक है, यह इतना बदसूरत है कि यह दर्द होता है। तुम वो क्यों कर रहे हो? यदि आपको वास्तव में करना है, तो क्या आप बस सरणी का उपयोग नहीं कर सकते? इस उदाहरण में 100 निश्चित है, इसलिए आप स्टैक पर एक सरणी का उपयोग किए बिना [] ing ... – Francesco

+2

"सेगमेंटेशन गलती" एक मंच-विशिष्ट घटना है। सी ++ भाषा यह वर्णन नहीं करती है कि यह क्या है। भाषा केवल यही कहती है कि कुछ परिभाषित किया गया है, और यदि ऐसा है, तो क्या करें। –

+1

मैंने सवाल कम कर दिया है, न कि क्योंकि मैं इसे एक बुरा सवाल मानता हूं, लेकिन क्योंकि आपने यह सुनिश्चित करने के लिए पर्याप्त समय नहीं लगाया कि आप जो पूछ रहे थे वह था जो आप पूछना चाहते थे (मूल कोड और वर्तमान संस्करण में कोड काफी है विभिन्न)।-2 प्रतिनिधि अंक ज्यादा नहीं हैं, लेकिन आपको भविष्य में थोड़ा और सावधान रहने के लिए याद दिलाना चाहिए, क्योंकि जब आप अन्य लोगों से मदद करने के लिए उत्तर देने का समय लेते हैं, और यह वह समय है जो बाद में प्रश्न को सुधारने पर बर्बाद हो जाता है पर। –

उत्तर

16

नहीं, यह सुरक्षित नहीं है।

reserve() के बाद, वेक्टर को capacity() तक पहुंचने तक स्टोरेज को पुन: आवंटित नहीं करने की गारंटी है।

हालांकि, मानक यह नहीं कहता कि वेक्टर कार्यान्वयन size() और capacity() के बीच भंडारण के साथ क्या कर सकता है। शायद इसका इस्तेमाल कुछ आंतरिक डेटा के लिए किया जा सकता है - कौन जानता है? शायद पता स्थान सिर्फ आरक्षित है और वास्तविक रैम में मैप नहीं किया गया है?

[0.. आकार) के बाहर तत्वों तक पहुंच अपरिभाषित व्यवहार है। उस के लिए कुछ हार्डवेयर जांच हो सकता है।

+0

_why_ को इंगित करने के लिए ऊपर उठाया गया यह एक बुरा विचार है: आरक्षित स्मृति यूबी है और वेक्टर के माध्यम से 'आधिकारिक तौर पर' उपलब्ध नहीं है जब तक कि इसे 'आकार बदलें' या 'पुश'/'emplace'd' नहीं किया जाता है। –

2

वेक्टर पुनः आबंटन मौजूदा संकेत दिए गए, संदर्भ आदि रिजर्व को अमान्य कर एक पुनः आबंटन (23.3.6.2, [vector.capacity]) को चालू कर सकते हैं, लेकिन आप अंतिम पुनः आबंटन के बाद पहला तत्व का पता ले जा रहे हैं (जो इस मामले में शायद बिल्कुल नहीं होगा, लेकिन यह बिंदु के अलावा है)। तो मुझे कोड के साथ कोई समस्या नहीं दिख रही है।

+0

'memcpy (मेरा उदाहरण गलत था) की बजाय मेमसेट का उपयोग करने के लिए मेरा प्रश्न अपडेट किया गया। – larsmoa

2

पहले ध्यान दें कि आपके memset0x123 को एक बाइट में छोटा कर देगा और लिखेंगे, एक चार बाइट पैटर्न नहीं लिख रहा है। std::vector<int> vec(100, whatever_value_you_want);

हालांकि सवाल यह पॉड प्रकार के लिए विशेष रूप से काम करने के लिए करता है, तो संकलक कुछ भी के लिए आवंटित अंतरिक्ष का उपयोग नहीं करता दिखाई दे सकते हैं जवाब देने के लिए:

फिर, ऐसा मत करो, बस कंटेनर का उपयोग करें। निश्चित रूप से अगर कोई resize, insert, push_back इत्यादि कहता है तो यह जो कुछ भी आपने पहले ही स्मृति में लिखा है और वेक्टर का आकार भी गलत होगा। ऐसे कोड लिखने का कोई कारण नहीं है।

संबंधित मुद्दे