2012-06-29 15 views
5

मुझे पिछले कुछ घंटों में किसी समस्या पर परेशानी हो रही है, हालांकि मुझे समझ में आया। यहां मेरी परेशानी है:स्ट्रैपी के साथ char * और char [] के बीच अंतर()

void cut_str(char* entry, int offset) { 
    strcpy(entry, entry + offset); 
} 

char works[128] = "example1\0"; 
char* doesnt = "example2\0"; 

printf("output:\n"); 

cut_str(works, 2); 
printf("%s\n", works); 

cut_str(doesnt, 2); 
printf("%s\n", doesnt); 

// output: 
// ample1 
// Segmentation: fault 

मुझे लगता है कि चार */char [] के बारे में कुछ महत्वपूर्ण है जो मुझे यहां नहीं मिल रहा है।

+0

यह प्रश्न अक्सर पूछे जाते हैं। कृपया देखें, उदाहरण के लिए, http://stackoverflow.com/questions/10186765/char-array-vs-char-pointer-in-c और http://stackoverflow.com/questions/4090434/strtok-char-array-versus -char-pointer –

+0

संभावित डुप्लिकेट [सी में [एस] और char * s के बीच क्या अंतर है?] (http://stackoverflow.com/questions/1704407/what-is-the-difference-between -char-s-and-char-s-in-c) –

उत्तर

11

अंतर doesnt अंक में है जो एक स्ट्रिंग स्थिरांक से संबंधित है, और इसलिए लिखने योग्य नहीं है।

आप इस

char works[128] = "example1\0"; 

संकलक प्रतियां एक लिखने योग्य सरणी में एक गैर-लिखने योग्य स्ट्रिंग की सामग्री करते हैं। रास्ते में \0 की आवश्यकता नहीं है।

जब आप ऐसा करते हैं, हालांकि,

char* doesnt = "example2\0"; 

संकलक सूचक एक गैर लिखने योग्य स्मृति क्षेत्र की ओर इशारा करते हैं। फिर, \0 संकलक द्वारा डाला जाएगा।

यदि आप gcc का उपयोग कर रहे हैं, तो आप स्ट्रिंग अक्षर के साथ लिखने योग्य char * प्रारंभ करने के बारे में आपको चेतावनी दे सकते हैं। विकल्प -Wwrite-strings है।

warning: initialization discards qualifiers from pointer target type 

उचित तरीके से घोषित करने के लिए अपने doesnt सूचक इस प्रकार है:: आप एक चेतावनी है कि इस तरह दिखता है मिल जाएगा

const char* doesnt = "example2\0"; 
+0

"संकलक एक गैर-लिखने योग्य स्ट्रिंग की सामग्री को एक लिखने योग्य सरणी में प्रतिलिपि बनाता है" - बिल्कुल नहीं। "example1 \ 0" यहां एक गैर-लेखन योग्य स्ट्रिंग नहीं है, यह स्ट्रिंग अक्षर है - एक पूरी तरह से वाक्य रचनात्मक तत्व। इस संदर्भ में इसे प्रारंभकर्ता के रूप में उपयोग किया जा रहा है। –

+0

"आपको char * doesnt = ... line" के बारे में चेतावनी प्राप्त होनी चाहिए "- नहीं, वास्तव में, नहीं। सौभाग्य से कोई संकलक ऐसा नहीं करता है। –

+1

@ जिमबाल्टर जी ++ करता है: "चेतावनी: स्ट्रिंग स्थिर से 'char *' में रूपांतरण को बहिष्कृत किया गया"। यह काफी सी संकलक नहीं है, लेकिन मैं इसे नहीं बना रहा था :) – dasblinkenlight

3

यह स्टैक पर 128 बाइट्स आबंटित करता है, और करने के लिए नाम works का उपयोग करता है इसका पता देखें:

char works[128]; 

तो works लिखने योग्य स्मृति के लिए एक सूचक है।

यह एक स्ट्रिंग शाब्दिक है, जो केवल पढ़ने के लिए स्मृति में है बनाता है, और इसका पता का उल्लेख करने के नाम doesnt उपयोग करता है:

char * doesnt = "example2\0"; 

आप क्योंकि यह स्मृति को लिखने योग्य के लिए अंक, works करने के लिए डेटा लिख ​​सकते हैं। आप doesnt पर डेटा नहीं लिख सकते हैं, क्योंकि यह केवल पढ़ने के लिए स्मृति को इंगित करता है।

इसके अलावा, ध्यान दें कि आपको "\0" के साथ अपने स्ट्रिंग अक्षर को समाप्त करने की आवश्यकता नहीं है, क्योंकि सभी स्ट्रिंग अक्षर स्ट्रिंग के अंत में शून्य बाइट जोड़ते हैं।

+0

नहीं, 'वर्क्स' एक सरणी वस्तु है, सूचक नहीं। (इसका नाम अधिकांश संदर्भों में सूचक अभिव्यक्ति के लिए क्षय हो जाता है।) –

+0

"यह स्टैक पर 128 बाइट आवंटित करता है" - हम स्टोरेज क्लास को नहीं जानते हैं; यह बाहरी हो सकता है। और कीथ नोट्स के रूप में, सरणी पॉइंटर्स नहीं हैं। (एक परिणाम यह है कि 'आकार (काम करता है)! = Sizeof ((char *) काम करता है) ')। –

4

प्रकार char[] और char * काफी समान हैं, इसलिए आप इसके बारे में सही हैं। अंतर तब होता है जब प्रकार की वस्तुओं को प्रारंभ किया जाता है।टाइप करने के लिए आपकी ऑब्जेक्ट works, इसमें स्टैक पर आवंटित वैरिएबल स्टोरेज के 128 बाइट्स हैं। आपकी ऑब्जेक्ट doesnt, char * टाइप करें, में स्टैक पर कोई संग्रहण नहीं है।

कहाँ बिल्कुल doesnt की स्ट्रिंग संग्रहीत किया जाता है सी मानक द्वारा निर्दिष्ट नहीं है, लेकिन सबसे अधिक संभावना यह भरी हुई है जब आपके प्रोग्राम निष्पादन के लिए भरी हुई है एक nonmodifiable डेटा खंड में संग्रहित है। यह परिवर्तनीय भंडारण नहीं है। इस प्रकार जब आप इसे बदलने की कोशिश करते हैं तो segfault।

+0

"अंतर झूठ है" - सरणी और पॉइंटर्स के बीच अन्य महत्वपूर्ण, अंतर हैं। यहां मुद्दा वास्तव में इसके बारे में नहीं है, लेकिन इस तथ्य के बारे में जो एक स्ट्रिंग स्थिर को इंगित नहीं करता है, और मानक कहता है कि इसे संशोधित करने के परिणाम अपरिभाषित हैं। –

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