2012-03-30 13 views
37
#include "stdio.h" 
#include "string.h" 

main() 
{ 

    char string[] = "october"; // october is 7 letters 

    strcpy(string, "september"); // september is 9 letters 

    printf("the size of %s is %d and the length is %d\n\n", string, sizeof(string), strlen(string)); 

    return 0; 
} 

आउटपुट:sizeof बनाम strlen

सितंबर के आकार 8 और लंबाई 9

वहाँ कुछ मेरी वाक्य रचना या क्या गलत है क्या है?

+10

आप सरणी 'स्ट्रिंग' के अंत में लिख रहे हैं। यह अपरिभाषित व्यवहार है। 'स्ट्रिंग' में केवल 8 वर्ण (7 "अक्टूबर" के लिए 7 और शून्य टर्मिनेटर के लिए 1) हो सकते हैं। जब आप 'strcpy' कहते हैं, तो आप इसमें 10 वर्ण लिख रहे हैं (9 "सितंबर" के लिए 9 और शून्य टर्मिनेटर के लिए 1), जिसका अर्थ है कि आप सरणी के अंत से पहले चले गए हैं और आसन्न स्मृति को ओवरराइट कर रहे हैं। – Marlon

+11

ध्यान दें कि 'sizeof' की गणना * संकलन * समय पर की जाती है जहां' strlen' रन टाइम है। – Naveen

+5

@ नवीन: जागरूक रहें कि यह जरूरी नहीं है कि वीएलए शामिल हैं। – caf

उत्तर

1

आपकी गंतव्य सरणी 8 बाइट्स ("अक्टूबर" प्लस \ 0 की लंबाई) है और आप उस सरणी में 9 वर्ण डालना चाहते हैं।

man strcpy कहता है: यदि एक स्ट्रैपी() की गंतव्य स्ट्रिंग पर्याप्त नहीं है, तो कुछ भी हो सकता है।

कृपया मुझे बताओ कि क्या तुम सच में, क्या करना चाहते हैं क्योंकि यह बुरा लंबा रास्ता

+0

यह आकार के काम को समझने के लिए एक परीक्षण कार्यक्रम है() – beparas

33

sizeof और strlen() अलग बातें बदबू आ रही है। इस मामले में, अपने घोषणा में

char string[] = "october"; 

char string[8] = "october"; 

के रूप में ही तो संकलक बता सकता है कि string के आकार 8. है यह संकलन समय इस करता है।

हालांकि, strlen() रन समय पर स्ट्रिंग में वर्णों की संख्या की गणना करता है। इसलिए, strcpy() पर कॉल करने के बाद, string में अब "सितंबर" है। strlen() अक्षरों की गणना करता है और उनमें से 9 पाता है। ध्यान दें कि आपने "सितंबर" को पकड़ने के लिए string के लिए पर्याप्त स्थान आवंटित नहीं किया है। यह अपरिभाषित व्यवहार है।

3

आउटपुट सही है क्योंकि

पहले बयान स्ट्रिंग आकार संकलक कि है 7 + 1 द्वारा आवंटित किया गया था

दूसरा बयान (अक्टूबर संकलन समय पर अशक्त टर्मिनेटर के लिए 7 बाइट्स & 1 बाइट है): आप कर रहे हैं सितंबर की प्रतिलिपि बनाना (9 बाइट्स से 8 बाइट स्ट्रिंग);

वहाँ आप के लिए

8 बाइट (अभी भी strlen() सितम्बर के लिए काम नहीं करेगा यह शून्य चरित्र नहीं है)

+1

स्ट्रिंग शाब्दिक '" सितंबर "' निहित रूप से शून्य चरित्र होता है, इसलिए 'स्ट्रेल() 'काम करेगा, अगर प्रोग्राम पहले से क्रैश नहीं हुआ है (लेखन के कारण 'स्ट्रिंग' सरणी के अंत से पहले) –

-1

के रूप में सितंबर के आकार मिल गया आप इस उदाहरण में buffer overflow समस्या को खत्म करना होगा। ऐसा करने का एक तरीका - strncpy का उपयोग करना है:

memset(string, 0, sizeof(string)); 
strncpy(string, "september", sizeof(string)-1); 
+1

नहीं, नहीं, नहीं। 'strncpy()', इसके नाम के बावजूद, ** स्ट्रिंग्स ** के साथ कुछ भी करने का गलत टूल है। उपर्युक्त उदाहरण में, परिणामी 'स्ट्रिंग' एक * स्ट्रिंग * नहीं होगी क्योंकि इसके 8 तत्वों में से कोई भी शून्य टर्मिनेटर नहीं होगा। – pmg

+0

गलत उपकरण क्यों है? मैंने स्ट्रिंग समाप्ति समस्या तय की है। –

+0

तारों के लिए यह गलत उपकरण है क्योंकि यह शून्य टर्मिनेटर के लिए खाता नहीं है जो प्रत्येक स्ट्रिंग में परिभाषा के अनुसार मौजूद है ('strncpy() 'डिज़ाइन इसे केवल उपयोगी बनाता है ... errr ... * un-terminated तार *)। सुनिश्चित करें कि आपके पास स्थान है और 'strcpy() '(या, यदि आप बीएसडी-आईएमएस का उपयोग कर सकते हैं, तो' strlcpy()' का उपयोग करें)। – pmg