2011-12-22 8 views
21

मैं सोच रहा था मेरी धारणा है कि पहले मैं स्मृति में 12 वर्ण लेकिन में काम के लिए जगह आवंटित था अगली पंक्ति स्टैक पर एक चार सरणी बनाती है और इसका मेमोरी पता परीक्षण करने के लिए पास किया जाता है। तो मुफ्त() ढेर पर जगह जारी करने की कोशिश करता है जिसकी अनुमति नहीं है। क्या वो सही है?स्मृति का आवंटन और क्यों निम्नलिखित कोड isnt't</p> <pre><code>int main(int argc, char **argv) { char *test = (char*) malloc(12*sizeof(char)); test = "testingonly"; free(test); } </code></pre> <p>काम कर इस बारे में सोच करने के बाद सी में स्ट्रिंग को बचाने

तो ढेर पर एक स्ट्रिंग को बचाने के लिए सही दृष्टिकोण क्या होगा? क्या निम्नलिखित एक आम तरीका है?

int main(int argc, char **argv) 
{ 
    char *test = (char*) malloc(12*sizeof(char)); 
    strcpy(test, "testingonly"); 
    free(test); 
} 
+4

पहला समाधान एक क्लासिक स्मृति रिसाव को दिखाता है; आपको कुछ आवंटित मेमोरी के लिए पॉइंटर मिलता है, फिर जब आप 'test' के लिए स्ट्रिंग अक्षर को पॉइंटर असाइन करते हैं तो इसका एकमात्र संदर्भ खो देते हैं। इसके बाद, आवंटित स्मृति - एक रिसाव का संदर्भ देने के लिए आपके लिए कोई वैध तरीका नहीं है। –

+2

कभी भी सी में मॉलोक के नतीजे टाइप न करें, यह व्यर्थ है और केवल बग और कंपाइलर चेतावनियों को छुपाता है। – Lundin

+2

हां - 'strcpy' या' strncpy' या 'memcpy' का उपयोग करें। strncpy strcpy से बेहतर है, क्योंकि यह अधिकतम एन वर्णों पर प्रतिलिपि करते समय बफर ओवररन समस्या से बचने में मदद करता है। –

उत्तर

8

आपने पहले से ही अपने प्रश्न का उत्तर दिया है। अनिवार्य रूप से, स्ट्रिंग कॉपी स्ट्रिंग का उचित तरीका है।

+0

जब तक आप जानते हैं कि उचित मेमोरी गंतव्य स्ट्रिंग में आवंटित कर दी गई है, और दोनों तारों को निरस्त कर दिया गया है। – Dave

5

पहला संस्करण स्टैक पर एक स्ट्रिंग नहीं बनाता है, लेकिन आप सही हैं कि आपको असाइनमेंट के बाद free की अनुमति नहीं है। स्ट्रिंग अक्षर आमतौर पर स्मृति के निरंतर/केवल-पढ़ने वाले खंडों में संग्रहीत होते हैं। असाइनमेंट कुछ भी कॉपी नहीं करता है, बस test मेमोरी के उस क्षेत्र को इंगित करता है। आप इसे मुक्त नहीं कर सकते। आप उस स्ट्रिंग को भी संशोधित नहीं कर सकते हैं।

कोड का आपका दूसरा भाग सही और सामान्य है। यदि आपके कार्यान्वयन में हो तो आप strdup पर भी देखना चाहेंगे।

+0

निरंतर/केवल-पढ़ने वाले अनुभागों के लिए +1 –

+0

'strncpy' * strcpy' का एक सुरक्षित संस्करण नहीं है। यह लक्ष्य सरणी unterminated छोड़ सकते हैं। यह शायद ही कभी सही समाधान है। –

+0

@Keith: ठीक है, उस संदर्भ को हटा दिया गया है। 'strdup' हालांकि अच्छा है (मान लीजिए कि आप अपना इनपुट 1 जानते हैं। वैध सी स्ट्रिंग और 2. स्वीकार्य आकार का - जो भी आपके ऐप के लिए है)। – Mat

4

ठीक है आप सही हैं। अब कोड के पहले टुकड़े की जांच करें।

char *test = (char*) malloc(12*sizeof(char)); 

ऊपर कोड कोई समस्या नहीं है।

test = "testingonly"; 

यहाँ आप सूचक test स्मृति रिसाव के लिए अग्रणी संशोधित। और जब आप मुक्त करने का प्रयास करते हैं तो आप वास्तविक आवंटित सूचक को मुक्त नहीं कर रहे हैं, लेकिन एक "testonly" शाब्दिक ओर इशारा करते हैं। निरंतर स्मृति के लिए शाब्दिक बिंदु जिन्हें सामान्य परिदृश्यों में ओवरराइड नहीं किया जा सकता है।

अब कोड के दूसरे भाग के बारे में, यह ठीक काम करेगा क्योंकि आपने डेटा को स्पष्ट रूप से कॉपी किया है, जहां से शाब्दिक है जहां आपका test इंगित कर रहा है।

आपके दूसरे बिंदु पर हाँ strcpy एक सामान्य तरीका है। यदि आप कच्चे बाइट्स की प्रतिलिपि बना रहे हैं तो अन्य तरीके 'memcpy' हैं।

नोट: साहित्य स्टैक पर संग्रहीत नहीं हैं। लेकिन आप स्थान को संशोधित नहीं कर सकते हैं जहां अक्षर संग्रहित होते हैं।

+0

+1 "यह ठीक काम करेगा क्योंकि आपने डेटा को स्पष्ट रूप से कॉपी किया है, जहां से आपका परीक्षण ढेर करने के लिए शाब्दिक रहता है जहां आपका परीक्षण इंगित कर रहा है" –

57
char *test = (char*) malloc(12*sizeof(char)); 

     +-+-+-+-+-+-+-+-+-+-+-+-+ 
test--->|x|x|x|x|x|x|x|x|x|x|x|x| (uninitialized memory, heap) 
     +-+-+-+-+-+-+-+-+-+-+-+-+ 

test = "testingonly"; 

     +-+-+-+-+-+-+-+-+-+-+-+-+ 
test + |x|x|x|x|x|x|x|x|x|x|x|x| 
    | +-+-+-+-+-+-+-+-+-+-+-+-+ 
    | +-+-+-+-+-+-+-+-+-+-+-+-+ 
    +->|t|e|s|t|i|n|g|o|n|l|y|0| 
     +-+-+-+-+-+-+-+-+-+-+-+-+ 

free(test); // error, because test is no longer pointing to allocated space. 

इसके बजाय सूचक test बदलने की है, तो आप आवंटित जगह उदा का उपयोग कर में स्ट्रिंग "testingonly" कॉपी करने की जरूरत है strcpy या strdup का उपयोग करें। ध्यान दें कि malloc और strdup जैसे कार्य NULL जैसे अपर्याप्त स्मृति उपलब्ध हैं, और इस प्रकार जांच की जानी चाहिए।

char *test = (char*) malloc(12*sizeof(char)); 
strcpy(test, "testingonly"); 

     +-+-+-+-+-+-+-+-+-+-+-+-+ 
test--->|t|e|s|t|i|n|g|o|n|l|y|0| 
     +-+-+-+-+-+-+-+-+-+-+-+-+ 

या

char *test = strdup("testingonly"); 

     +-+-+-+-+-+-+-+-+-+-+-+-+ 
test--->|t|e|s|t|i|n|g|o|n|l|y|0| 
     +-+-+-+-+-+-+-+-+-+-+-+-+ 
+4

+1 इसे समझाने में आपके प्रयास की सराहना करता है। – dicaprio

+0

धन्यवाद !!!! महान –

0

कोड

#include <stdio.h> 
int main(int argc, char **argv) 
{ 
    char *test = (char*) malloc(12*sizeof(char)); 
    strcpy(test, "testingonly"); 
    printf("string is: %s\n",test); 
    free(test); 
    return 0; 
} 

काम करेंगे

0

यह स्मृति आवंटित करने के लिए है:

char *string; 
string = (char *) malloc(15); 

इस डेटा को बचाने के लिए है:

strcpy(str, "kavitajain"); 
printf("String = %s, Address = %u\n", str, str); 
संबंधित मुद्दे