2009-11-20 15 views
14
पर चार सरणी और सी में सूचक के साथ

तो मैं निम्नलिखित कार्यक्रम है:विभाजन दोष लिनक्स

int main(){ 
    char* one = "computer"; 
    char two[] = "another"; 
    two[1]='b'; 
    one[1]='b'; 
    return 0; 
} 

यह लाइन "एक [1] = 'बी'" जो समझ में आता है पर segfaults क्योंकि स्मृति कि सूचक "एक" अंक केवल स्मृति में पढ़ने के लिए होना चाहिए। हालांकि, सवाल यह है कि रेखा "दो [1] = 'बी'" segfault क्यों नहीं है? जीसीसी से असेंबली आउटपुट को देखते हुए:

.file "one.c" 
     .section  .rodata 
.LC0: 
     .string "computer" 
.LC1: 
     .string "another" 
     .text 
.globl main 
     .type main, @function 
main: 

हम देखते हैं कि दोनों तार रॉडटा सेक्शन में हैं इसलिए वे केवल पढ़ रहे हैं। तो फिर लाइन कैसे आती है "दो [1] = 'बी' segfault नहीं है?

+0

भी देखें अलग लेकिन संबंधित सवाल http://stackoverflow.com/questions/

char two[] = {'a', 'n', 'o', 't', 'h'. 'e', r', '\0'}; 

आप चर के साथ एक चरित्र सरणी को प्रारंभ कर सकते हैं, इस तरह के:

यह के बराबर है 1770062/परिभाषित-पॉइंटर-टू-स्टेटिक-स्ट्रिंग/1770067 # 1770067 –

उत्तर

35

one सीधे केवल पढ़ने के लिए पृष्ठ में स्थित स्ट्रिंग पर इंगित करता है। दूसरी ओर, two स्टैक पर आवंटित एक सरणी है और कुछ स्थिर डेटा के साथ शुरू किया गया है। रन टाइम पर, निष्पादन योग्य के केवल पढ़ने के अनुभाग में स्ट्रिंग को स्टैक पर कॉपी किया जाएगा। आप जो संशोधित कर रहे हैं वह स्टैक पर उस स्ट्रिंग की प्रति है, केवल पढ़ने योग्य स्मृति पृष्ठ नहीं ।

एक उच्च स्तर परिप्रेक्ष्य में देखने की भाषा की दृष्टि से, "abcd", प्रकार const char* की अभिव्यक्ति और नहीं char* है। इस प्रकार अपरिभाषित व्यवहार में इस तरह के एक अभिव्यक्ति परिणामों से बताया मूल्य को संशोधित। बयान +०१२३२२११४३३केवल एक चर में स्ट्रिंग में सूचक को संग्रहीत करता है (असुरक्षित रूप से, क्योंकि यह const संशोधक को कास्टिंग कर रहा है)। char two[] = "something"; पूरी तरह से अलग है। यह वास्तव में एक सरणी घोषित कर रहा है और इसे शुरू कर रहा है, int a[] = {1,2,3}; की तरह। यहां उद्धरणों में स्ट्रिंग प्रारंभिक अभिव्यक्ति है।

+3

वाह ... मैं लगभग 5 वर्षों से सी में प्रोग्रामिंग कर रहा हूं और मुझे पता नहीं था कि 'char []' निरंतर डेटा की एक प्रति बना है। मैंने हमेशा सोचा कि '[]' '*' लिखने का सिर्फ एक प्रशंसक तरीका था। धन्यवाद! +1 – Earlz

+3

मैं एसोसिएशन को स्पष्ट बनाने के प्रयास में अक्सर 'char str [] = {"Something"} लिखता हूं। – LnxPrgr3

+0

@ मेहदाद: क्रिस्टल स्पष्ट !! :) –

1

रॉडाटा सेक्शन में दिखाई देने वाला "दूसरा" यह है कि इसे प्रारंभ होने पर सरणी two में कॉपी किया जाएगा। दूसरी तरफ स्ट्रिंग "कंप्यूटर" के पते को एक को असाइन किया जाएगा।

तो, one केवल पढ़ने के लिए खंड (और इसलिए लिखने पर segfault) को इंगित कर रहा है जबकि two स्टैक पर आवंटित किया जाएगा और फिर "दूसरा" इसकी प्रतिलिपि बनाई जाएगी।

0

दूसरा रूप शाब्दिक स्ट्रिंग की प्रतिलिपि बनाकर एक सरणी बनाता है। के रूप में

char c = 'a'; 
char two[] = {'a', 'n', c, '\0'}; 
संबंधित मुद्दे