2010-06-04 17 views
7

पर स्मृति आवंटित करना क्या यह एक char * को स्मृति आवंटित करने का सही तरीका है।चार * सी भाषा

char* sides ="5"; 

char* tempSides; 

tempSides = (char*)malloc(strlen(inSides) * sizeof(char)); 
+0

@brickner क्या strlen में यह, strlen (अंदर) + 1 – boom

उत्तर

14

लगभग। स्ट्रिंग्स को निरस्त कर दिया जाता है, इसलिए आप संभवतः न्यूल बाइट को स्टोर करने के लिए एक अतिरिक्त बाइट आवंटित करना चाहते हैं। यही है, भले ही sides 1 वर्ण लंबा है, यह वास्तव में 2 बाइट्स है: {5, '\0'}।

तो यह होगा:

tempSides = (char *)malloc((strlen(sides)+1)*sizeof(char)); 

और यदि आप चाहते हैं में इसे कॉपी:

strcpy(tempSides, sides); 
+8

के बारे में तुम्हारा मतलब है '\ 0' जब आप शून्य कहते हैं। '\ 0' शून्य है, न कि पूर्ण। –

+0

ध्यान दें कि 'sizeof (char)' द्वारा गुणा करना अनचाहे है; 'sizeof (char)' को परिभाषित किया गया है 1. – caf

+2

@caf: सही है, लेकिन इसे छोड़कर इसे आवश्यक होने पर wchar_t या TCHAR को कोड अनुकूलित करना मुश्किल हो जाता है - यदि कोई गुणा नहीं है तो इसका उपयोग करने के लिए भूलने का जोखिम है। – sharptooth

1

वहाँ उस के साथ एक समस्या है। tempSides आकार 1 की स्मृति के एक प्रारंभिक ब्लॉक को इंगित करेगा। यदि आप tempSides में स्ट्रिंग स्ट्रिंग को प्रतिलिपि बनाना चाहते हैं, तो स्ट्रिंग के लिए शून्य टर्मिनेटर को पकड़ने के लिए आपको आकार को एक बाइट आवंटित करने की आवश्यकता होगी। Strlen() द्वारा दिए गए मान में स्ट्रिंग के अंत में शून्य टर्मिनेटर शामिल नहीं है।

1

नहीं, वास्तव में नहीं। जैसा कि अन्य ने पहले से ही नोट किया है, आपको एनयूएल टर्मिनेटर के लिए जगह आवंटित करने की आवश्यकता है।

इसके अलावा, आपको आमतौर पर malloc से वापसी कास्ट करना चाहिए। यह एक बग को कवर कर सकता है जहां आप सही शीर्षलेख #include भूल गए हैं। sizeof(char) से गुणा करने पर भी व्यर्थ है के बाद से मानकों (दोनों C और C++) sizeof(char) परिभाषित हमेशा होने के लिए 1.

अंत में, malloc के लिए हर कॉल परिणाम की परीक्षा में शामिल होना चाहिए। मैं एक समारोह में पूरी बात लपेट चाहते हैं:

char *dupe_string(char const *string) { 
    char *temp; 
    if (NULL!=(temp=malloc(strlen(string)+1))) 
     strcpy(temp, string); 
    return temp; 
} 
3

के रूप में बताया गया है, तो आप समाप्त NUL chararacter के लिए जगह का आवंटन याद किया। लेकिन मैं कुछ अन्य चीजों को इंगित करना चाहता था जो आपके कोड को अधिक संक्षिप्त बना सकते हैं।

परिभाषा के अनुसार, sizeof(char) हमेशा 1 है, तो आप करने के लिए अपने आवंटन लाइन को छोटा कर सकते हैं:

tempSides = (char*)malloc(strlen(inSides) + 1); 

एक और बात यह है कि इस लगता है कि आप स्ट्रिंग नकल करने कर रहे हैं। वहाँ एक समारोह है कि करता है में बनाया गया है कि आप के लिए:

tempSides = strdup(inSides); 

यह लंबाई हो रही हैंडल, बाइट्स की सही संख्या का आवंटन और डेटा को कॉपी।

9

ध्यान दें कि:

  1. स्ट्रिंग्स शून्य समाप्त (\ 0), और strlen() यह शामिल नहीं किये जाते हैं;
  2. परिभाषा के अनुसार, sizeof (char) 1 (बाइट) है, इसलिए इसकी आवश्यकता नहीं है;
  3. यदि आप सी (सी ++ नहीं) कंपाइलर का उपयोग करते हैं, तो इसे char * पर डालने की कोई आवश्यकता नहीं है;

ताकि होगा:

char *tempSides = malloc(strlen(inSides) + 1); 

फिर भी, अगर आप करना चाहते हैंinSides की सामग्री को नकल, आप strdup, जैसे उपयोग कर सकते हैं:

char *tempSides = strdup(inSides); 
if (tempSides != NULL) { 
    // do whatever you want... 
    free(tempSides); 
} 
0

तत्व गिनती गुणा sizeof(char) द्वारा व्यक्तिगत वरीयता का मामला है, क्योंकि sizeof(char) हमेशा 1 होता है। हालांकि, यदि आप स्थिरता के लिए ऐसा करते हैं, तो बेहतर उपयोग टी वह स्पष्ट रूप से प्रकार निर्दिष्ट करने के बजाय तत्व आकार निर्धारित करने के लिए प्राप्तकर्ता सूचक प्रकार। और malloc

tempSides = malloc(strlen(inSides) * sizeof *tempSides); 
बेशक

, का परिणाम जब शून्य समाप्त तार आप समाप्त शून्य चरित्र के लिए अतिरिक्त जगह आवंटित करने के लिए याद करने के लिए है के साथ काम कर डाली नहीं है। यह कहने का कोई तरीका नहीं है कि tempSides इस मामले में शून्य-समाप्त स्ट्रिंग बनाने का आपका इरादा है, इसलिए मैं यह नहीं कह सकता कि आपको इसकी आवश्यकता है या नहीं।

+0

कोई रास्ता नहीं? 'स्ट्रेलन' को कॉल करते समय उसे बेहतर ढंग से शून्य-समाप्त तारों का उपयोग करना चाहिए ... यदि वह अपने स्वयं के स्ट्रेलन का उपयोग करता है, तो मैं वास्तव में उसके बाद रखरखाव प्रोग्रामर नहीं बनना चाहता हूं। ;) – Secure

+1

@ सुरक्षित: इसका मतलब केवल 'इनसाइड' शून्य-समाप्त है। कोड में कोई संकेत नहीं है कि 'tempSides' को भी शून्य-समाप्त किया जाना चाहिए। – AnT

0

tempSides के आवंटन गतिशील स्मृति के सही तरीके के रूप में नीचे दिखाया गया है:

char* sides ="5"; 
char* tempSides; 
tempSides = (char*)malloc((strlen(sides) + 1) * sizeof(char)); 

char* भंडार एक स्ट्रिंग डेटा, char[] के समान है। स्ट्रिंग्स null (\0) समाप्त हो गई हैं। तो अतिरिक्त एक बाइट null चरित्र भंडारण के लिए आवंटित किया जाना चाहिए।

डायनामिक रूप से आवंटित मेमोरी ब्लॉक को उपयोग के बाद free() का उपयोग करके मुक्त किया जाना चाहिए। अगर मुक्त नहीं होता है, तो स्मृति रिसाव होगा।

free(tempSides); 

एक स्मृति मुक्त हो जाता है, NULL यह एक झूलने सूचक होने से रोक देना चाहिये।

tempSides = NULL; 
संबंधित मुद्दे