वास्तव में यह कैसा लगता है, यह मानकर कि आप संक्षिप्त रूप में उपयोग किए जाते हैं जिसमें C और UNIX शब्द प्रदान करते हैं, यह स्ट्रिंग को डुप्लिकेट करता है :-)
यह ध्यान में रखते हुए कि यह वास्तव में ISO C मानक का हिस्सा नहीं है (a) (यह एक POSIX चीज है), यह प्रभावी रूप से निम्न कोड के समान ही कर रहा है:
char *strdup(const char *src) {
char *dst = malloc(strlen (src) + 1); // Space for length plus nul
if (dst == NULL) return NULL; // No memory
strcpy(dst, src); // Copy the characters
return dst; // Return the new string
}
दूसरे शब्दों में:
यह पुराने स्ट्रिंग को पकड़ने के लिए पर्याप्त मेमोरी आवंटित करने की कोशिश करता है (साथ ही स्ट्रिंग के अंत को चिह्नित करने के लिए एक '\ 0' वर्ण)।
आवंटन में विफल रहा है, यह सेट errno
करने के लिए ENOMEM
और रिटर्न NULL
तुरंत। की स्थापना errno
करने के लिए ENOMEM
कुछ न कुछ है malloc
POSIX में करता है तो हम स्पष्ट रूप से हमारे में यह करने के लिए की जरूरत नहीं है strdup
। यदि आप POSIX के अनुरूप नहीं हैं , तो ISO C वास्तव में ENOMEM
मेरे अस्तित्व को अनिवार्य नहीं करता है इसलिए मैंने यहां (b) को शामिल नहीं किया है ।
अन्यथा आवंटन ने काम किया इसलिए हम पुराने स्ट्रिंग को नए स्ट्रिंग (c) में कॉपी करते हैं और नए पते को लौटाते हैं (जिसे कॉल करने वाला किसी बिंदु पर मुक्त करने के लिए जिम्मेदार है)।
ध्यान रखें कि यह वैचारिक परिभाषा है। अपने वेतन के लायक किसी भी पुस्तकालय लेखक ने इस्तेमाल किए जा रहे विशेष प्रोसेसर को लक्षित करते हुए भारी अनुकूलित कोड प्रदान किया हो सकता है।
(ए) हालांकि, कार्य शुरू करने वाले str
और निचले मामले के पत्र भविष्य के निर्देशों के लिए मानक द्वारा आरक्षित हैं। से C11 7.1.3 Reserved identifiers
:
प्रत्येक हेडर अपने संबंधित उप-खंड में सूचीबद्ध सभी पहचानकर्ताओं को घोषित या परिभाषित करता है, और * अपने संबंधित भविष्य के पुस्तकालय निर्देशों के उप-खंड में सूचीबद्ध पहचानकर्ताओं को वैकल्पिक रूप से घोषित या परिभाषित करता है। **
के लिए भविष्य की दिशाएँ मिल string.h
सकती हैं C11 7.31.13 String handling <string.h>
:
फंक्शन नाम, जो शुरू होता है str
, mem
या wcs
एक लोअरकेस अक्षर <string.h>
हेडर में घोषणाओं में जोड़ा जा सकता है ।
इसलिए अगर आप सुरक्षित रहना चाहते हैं तो आपको इसे कुछ और कहना चाहिए।
(बी) परिवर्तन मूल रूप से के if (d == NULL) return NULL;
साथ हो जाएगा :
if (d == NULL) {
errno = ENOMEM;
return NULL;
}
(ग) ध्यान दें कि मैं उस के strcpy
लिए उपयोग करता हूं क्योंकि यह स्पष्ट रूप से इरादा दिखाता है। कुछ कार्यान्वयनों में, यह तेज़ हो सकता है (चूंकि आप पहले से ही लंबाई जानते हैं) का उपयोग करना है memcpy
, क्योंकि वे डेटा को बड़ी मात्रा में या समानांतर में स्थानांतरित करने की अनुमति दे सकते हैं। या यह नहीं हो सकता है :-) अनुकूलन मंत्र # 1: "उपाय, अनुमान मत करो"।
किसी भी मामले में, क्या आपको उस मार्ग पर जाने का निर्णय लेना चाहिए, आप कुछ ऐसा करेंगे:
char *strdup(const char *src) {
size_t len = strlen(src) + 1; // String plus '\0'
char *dst = malloc(len); // Allocate space
if (dst == NULL) return NULL; // No memory
memcpy (dst, src, len); // Copy the block
return dst; // Return the new string
}