2011-05-23 8 views
5
#inlcude <stdio.h> 
#inlcude <stdlib.h> 
#inlcude <string.h> 

int main() { 
    char *buff = (char*)malloc(sizeof(char) * 5); 
    char *str = "abcdefghijklmnopqrstuvwxyz"; 

    memcpy (buff, name, strlen(str)); 

    while(*buff) { 
     printf("%c" , *buff++); 
    } 

    printf("\n"); 

    return 0; 
} 

यह कोड पूरी स्ट्रिंग "abc ... xyz" प्रिंट करता है। लेकिन "बफ" में उस स्ट्रिंग को पकड़ने के लिए पर्याप्त स्मृति नहीं है। कैसे memcpy() काम करता है? क्या यह realloc() का उपयोग करता है?क्या memcpy() realloc() का उपयोग करता है?

उत्तर

10

आपके कोड में अपरिभाषित व्यवहार है। अपने प्रश्न का उत्तर देने के लिए, NO, memcpyrealloc का उपयोग नहीं करता है। sizeof(buf)strlen(str) को समायोजित करने के लिए पर्याप्त होना चाहिए। कुछ भी कम एक दुर्घटना है।

आउटपुट मुद्रित किया जा सकता है क्योंकि यह एक छोटा प्रोग्राम है, लेकिन वास्तविक बड़े कोड में यह त्रुटियों को डीबग करना कठिन होगा। , करने के लिए अपने कोड को बदलें

const char* const str = "abcdefghijklmnopqrstuvwxyz"; 
char* const buff = (char*)malloc(strlen(str) + 1); 

इसके अलावा, *buff++ ऐसा नहीं करते हैं, क्योंकि आप स्मृति रिकॉर्ड खो देंगे (आप क्या आवंटित)। malloc() के बाद मेमोरी उपयोग खत्म हो जाने के बाद free(buff) करना चाहिए, अन्यथा यह एक स्मृति रिसाव है।

+3

+1। –

+0

मैं अपने वास्तविक एप्लिकेशन में एक स्ट्रिंग रखने के लिए इस बफर का उपयोग करना चाहता हूं। उस स्ट्रिंग की कोई पूर्वनिर्धारित लंबाई नहीं है। जब प्रोग्राम चल रहा है तो यह गतिशील रूप से बढ़ता है (कुछ अन्य तारों को जोड़ना ...)। जो समाधान मैंने पाया वह कुछ बड़ी स्मृति आवंटित कर रहा है (~ 1 केबी)। मैं जानना चाहता हूं कि इसके अलावा कोई अलग समाधान है? कृपया मदद करे। धन्यवाद। – shan

+0

@shan, तो आप उस उद्देश्य के लिए 'realloc()' (लेकिन 'memcpy()') का उपयोग नहीं कर सकते हैं। – iammilind

8

आपको पूरी स्ट्रिंग मुद्रित हो रही है, लेकिन यह सुरक्षित नहीं है और आप अनियंत्रित स्मृति से लिख रहे हैं और पढ़ रहे हैं। यह अपरिभाषित व्यवहार पैदा करता है।

memcpy कोई मेमोरी आवंटन नहीं करता है। यह आपके द्वारा प्रदान किए जाने वाले स्थानों से बस पढ़ता है और लिखता है। यह जांच नहीं करता है कि ऐसा करने के लिए ठीक है, और इस मामले में आप भाग्यशाली हैं यदि आपका प्रोग्राम क्रैश नहीं होता है।

+0

उत्तर के लिए धन्यवाद। लेकिन, अगर मुझे स्ट्रिंग की लंबाई पता नहीं है तो मैं पर्याप्त मेमोरी आवंटित करता हूं? मैं एक बफर बनाना चाहता हूँ। मैं गैर-आवंटित स्मृति से लिखने और पढ़ने से बचना चाहता हूं। मेरे कोड में मुझे क्या परिवर्तन करना है? कृपया सहायता कीजिए ? धन्यवाद – shan

+0

@shan - अगर आप 'memcpy' को कॉल कर रहे हैं, और आप जानते हैं कि आप कितनी मेमोरी कॉपी करने जा रहे हैं, तो आप जानते हैं कि आवंटित करने के लिए आपको कितनी मेमोरी चाहिए। एक स्ट्रिंग की लंबाई खोजने के लिए 'strlen' का उपयोग करें (यह समाप्ति शून्य वर्ण को दिखता है)। – sje397

+0

हां, आप 'strlen' का उपयोग करते हैं, जैसा कि आपने अपने' memcpy' के लिए किया था, एक विवरण को छोड़कर। 'Strlen' फ़ंक्शन समाप्ति शून्य वर्ण को गिनता नहीं है। इस प्रकार 'मॉलोक' और 'memcpy' दोनों में आपको 'strlen (str) + 1' का उपयोग करने की आवश्यकता है। इसके अलावा, आपको malloc में 'sizeof (char)' से गुणा करने की आवश्यकता नहीं है। परिभाषा के अनुसार 'sizeof (char) == 1'। – andrewdski

1

कैसे memcpy() काम करता है?

क्योंकि आपने अपरिभाषित व्यवहार का आह्वान किया है। अपरिभाषित व्यवहार ठीक वैसे ही काम कर सकता है जैसा आप उम्मीद करते हैं, और यह कुछ पूरी तरह से अलग कर सकता है। यह एक ही कार्यक्रम के विभिन्न रनों के बीच भी भिन्न हो सकता है। यह आपकी हार्ड डिस्क को भी प्रारूपित कर सकता है और फिर भी मानक के अनुरूप हो सकता है (हालांकि निश्चित रूप से यह असंभव है: पी)

अपरिभाषित व्यवहार का अर्थ है कि व्यवहार को सचमुच कुछ भी करने के लिए परिभाषित नहीं किया गया है। आप जो व्यवहार देख रहे हैं, उसके अलावा कुछ भी मान्य है। ध्यान दें कि यदि आप free की कोशिश करते हैं तो स्मृति आपके लक्षित प्लेटफ़ॉर्म के सी रनटाइम शायद शिकायत करेगी। ;)

1

नहीं memcpymalloc का उपयोग नहीं करता है। जैसा कि आपको संदेह है, आप buff के अंत में लिख रहे हैं। आपके सरल उदाहरण में, यह कोई स्पष्ट नुकसान नहीं करता है, लेकिन यह बुरा है। यहाँ सब एक 'असली' कार्यक्रम में गलत हो सकता है कि में से कुछ हैं:

  • आप नीचे दिए गए कुछ स्मृति में आवंटित पर घसीटना सकता है आपके buff बाद में सूक्ष्म (या इतना सूक्ष्म नहीं) कीड़े के लिए अग्रणी।
  • आप malloc और free द्वारा आंतरिक रूप से उपयोग हेडर पर घसीटना सकता है, उन कार्यों के लिए अपने अगले फोन पर दुर्घटनाओं या अन्य समस्याओं के लिए अग्रणी।
  • आप किसी ऐसे पते पर लिखना समाप्त कर सकते हैं जो आपकी प्रक्रिया में आवंटित नहीं किया गया है, इस मामले में आपका प्रोग्राम तुरंत क्रैश हो जाएगा। (मुझे लगता है यह आप क्या उम्मीद कर रहे थे है।)

malloc कार्यान्वयन कि तुच्छ गार्ड पृष्ठों के आसपास करने के लिए स्मृति आवंटित कर दिया हैं (आमतौर पर) कार्यक्रम इस तरह के मामलों में क्रैश हो।अन्य कार्यान्वयन इस का पता लगाएंगे, लेकिन केवल malloc या free पर अगली कॉल पर (या जब आप ढेर को जांचने के लिए एक विशेष फ़ंक्शन को कॉल करते हैं)।

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