2012-10-31 6 views
14

मैं दो कोड के ब्लॉक के बारे में new[] और delete[] है:पी = नई स्ट्रिंग [0] और पी = नई int [0] के बाद, स्ट्रिंग संस्करण क्रैश होने पर क्रैश क्यों होता है [] p?

1))

#include <string> 

int main() 
{ 
    std::string *p = new std::string[0]; 
    delete[] p; 

    return 0; 
} 

2 इस मामले में, मैं केवल बदल std::stringint

int main() 
{ 
    int *p = new int[0]; 

    delete[] p; 

    return 0; 
} 

मेरे सवाल यह है:

क्यों निम्न संदेश के साथ पहला कार्यक्रम दुर्घटनाओं (linux वातावरण में):

Segmentation fault (core dumped) 

लेकिन दूसरे कार्यक्रम किसी भी त्रुटि के बिना अच्छी तरह से काम करता है?

संपादित

संकलक: g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2

मैं सिर्फ g++ किसी भी तर्क के बिना उपयोग करने के लिए यह संकलन करने।

यदि यह एक कंपाइलर बग है, तो क्या उन्हें मानक के अनुसार क्रैश करना चाहिए या नहीं?

+2

एक संकलक बग – Andrey

+1

यह यहाँ क्रैश नहीं होता की तरह लग रहा। आप किस कंपाइलर का उपयोग कर रहे हैं (सटीक संस्करण के साथ) और आप इसे कैसे संकलित कर रहे हैं? – amaurea

+1

जी ++ (4.7 और 4.8) के साथ क्रैश, क्लैंग के साथ क्रैश नहीं होता है। मुझे लगता है कि यह एक जी ++ बग है। – kennytm

उत्तर

13

यह एक जीसीसी बग होना चाहिए। कि पूरे new[] अभिव्यक्ति को अनदेखा किया गया है और p अनियमित हो गया है, और फिर हम delete[] एक अनियमित सूचक जो क्रैश हो जाता है। हम -Wall साथ कार्यक्रम संकलन यदि यह आपको चेतावनी देगा कि

चेतावनी: 'पी' इस समारोह

जो स्पष्ट रूप से गलत है में अप्रारंभीकृत प्रयोग किया जाता है। अभिव्यक्ति new X[0] सी ++ 03 और सी ++ 11 (§5.3.4/7) दोनों में अच्छी तरह परिभाषित है, और यह क्लैंग में सही ढंग से काम करता है, इसलिए केवल तार्किक निष्कर्ष यह है कि यह एक जीसीसी बग है।


उन्मूलन के- new[] बग केवल मौजूद न होने पर प्रकार का निर्माण करने के लिए किसी भी गैर तुच्छ निर्माता है। और segfault होता है इस प्रकार के विनाशक है, क्योंकि delete[] तब अपरिष्कृत सूचक होने के लिए dereference की आवश्यकता होगी। इसलिए, यह std::string के लिए क्रैश होता है लेकिन int नहीं, क्योंकि int छोटा है और std::string नहीं है।


यह एक मध्यवर्ती चर, जैसे कि अभिव्यक्ति 0 सीधे करने के लिए मूल्यांकन नहीं किया जा सकता है का उपयोग करके चारों ओर काम किया जा सकता है:

size_t length = 0; 
std::string* p = new std::string[length]; 
// ... 
delete[] p; 
+0

मैं हैक काम करता है ... liveworkspace पर हैरान हूं मैं 3 व्यवहार है: मूल ओपी कोड (चेतावनी + दुर्घटना), इस काम के आसपास (कोई चेतावनी, कोई दुर्घटना) 'स्थिरांक लंबाई = 0 size_t का उपयोग कर,;,' (चेतावनी दुर्घटना नहीं)। मैं * प्यार * जीसीसी ... –

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