2015-10-14 1 views
5
std::map<int,int> bar; 

int foo(int key) 
{ 
    bar.erase(key); 
    return 1; 
}  

int main() 
{ 
    bar[0] = foo(0); 
    return 0; 
} 

जब बिजली की बाड़ के साथ स्मृति के उपयोग की जाँच जीसीसी 4.8 SEGS गलती के साथ संकलित इस कोड।C++ एसटीएल नक्शा :: ऑपरेटर [] एक प्रवेश पर किया हटाया जा रहा

LD_PRELOAD=libefence.so.0.0 ./a.out 

समस्या तथ्य यह है कि संकलक, एक कोड मानचित्र में एक नई प्रविष्टि आवंटित करने के लिए शुरू होता है कि उत्पन्न करता है तो foo() कार्यान्वित bar[0] में लाना मूल्य प्राप्त करने से आता है। foo() चलाते समय, प्रविष्टि नष्ट हो जाती है और कोड अंततः गैर-आवंटित स्मृति में लिखकर समाप्त होता है।

क्या ऑपरेशन के आदेश के तरीके को संकलक कार्यान्वयन पर निर्भर करता है, या यह सी ++ वर्तमान मानक द्वारा निर्दिष्ट है?

+2

कि ऐसा मत करो .. –

+1

भी http://stackoverflow.com/a/4183735 देखें। –

+0

अनुक्रमण और अनुक्रम बिंदुओं में देखें। यह अनिर्धारित है कि 'bar [0]' का मूल्यांकन 'foo (0)' से पहले किया जाएगा, यदि यह है (और ऐसा लगता है कि यह आपके लिए है) तो आप बड़ी परेशानी में हैं। – AndyG

उत्तर

5

मानक (§1.9 15) यह बताता है कि एक द्विआधारी ऑपरेटर के लिए दो ऑपरेंड के मूल्यांकन unsequenced है (जब तक कुछ विशिष्ट मामलों में):

अपवाद का उल्लेख नहीं, अलग-अलग ऑपरेटरों की ऑपरेंड के मूल्यांकन और व्यक्तिगत अभिव्यक्तियों के उप-अभिव्यक्तियों का अपवाद नहीं है।

इसका मतलब यह है कि यह जनादेश नहीं है कि काम आपरेशन के एक तरफ अन्य से पहले मूल्यांकन किया जाता है, और वास्तव में, यह इन unsequenced आपरेशन के आदेश पर निर्भर रहना अपरिभाषित व्यवहार है।

यह आमतौर पर फ़ंक्शन तर्कों के मूल्यांकन के क्रम के लिए भी सच है।

आप दो में अपने असाइनमेंट को तोड़ने की जरूरत है:

int result = foo(0); 
bar[0] = result; 
+0

"और वास्तव में, यह संचालन के क्रम पर निर्भर करने के लिए अपरिभाषित व्यवहार है" - यह आम तौर पर नहीं है। दो फ़ंक्शन कॉल का क्रम निर्दिष्ट नहीं है, लेकिन इसका मतलब है कि आप विश्वसनीय रूप से यह नहीं बता सकते कि कौन सा फ़ंक्शन पहले कॉल किया जाएगा। ऐसा ही होता है कि ओपी के मामले में, आदेश के आधार पर, एक लटकती संदर्भ का उपयोग किया जाएगा। * वह * व्यवहार को अनिर्धारित करता है, संचालन के विशिष्ट क्रम के आधार पर केवल तथ्य नहीं। यहां तक ​​कि अगर मैं 'प्रिंटफ ("हैलो,") + printf ("world!")' हैलो, दुनिया! 'प्रिंट करने के लिए, मैं या तो इच्छित आउटपुट या' दुनिया! हैलो, 'की गारंटी देता हूं। – hvd

+0

@ एचवीडी, हां, मेरा मतलब था कि यह यूबी अपर्याप्त संचालन के आदेश पर निर्भर है। – zneak

+0

ओह, ओह, शब्दावली मिश्रण-अप। फ़ंक्शन कॉल की वजह से यह "अनिश्चित रूप से अनुक्रमित" है, न कि मेरे उदाहरण में और ओपी के कोड में "अपूर्ण"। क्या आपको अभी भी लगता है कि यह यूबी है? – hvd

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