2009-07-26 17 views
6

जब एक सॉकेट recv का उपयोग कर के माध्यम से डेटा प्राप्त, मैंने देखा है कि, के साथ:चार सरणी बनाम चार सूचक

 
char buffer[4]; 
memset(buffer, 0, 4); 
recv(socket, buffer, 4, 0); 

मैं प्राप्त

mesgx

"मैसेज" जो मैंने भेजा है, कुछ यादृच्छिक पात्रों के साथ जोड़ा गया है।

अगर मैं

 
char * method = (char *) malloc(4); 
memset(buffer, 0, 4); 
recv(socket, buffer, 4, 0); 

बजाय का उपयोग करें, मैं प्राप्त

mesg

तो वहाँ कोई यादृच्छिक सामान मेरी स्ट्रिंग के साथ जोड़ दिया है। मुझे पता चला कि अगर मैं चार [5] का उपयोग करता हूं तो यह भी काम करता है, लेकिन मुझे वास्तव में समझ में नहीं आता है। क्या मॉलोक (4) वास्तव में 5 बाइट आवंटित करता है, पांचवां एनयूएल होता है?

उत्तर

16

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

उस स्थिति में जहां आपने स्टैक पर char buffer[4] आवंटित किया था, अगला बाइट 'x' होने के बाद कुछ अन्य सामानों के बाद हुआ, इसलिए आपकी स्ट्रिंग अभी तक जारी रही जब तक कि यह अगले एनयूएल बाइट नहीं मिला।

सॉकेट फ़ंक्शंस केवल बाइट्स के साथ सौदा करता है, और बाइट्स को पिछली एनयूएल या अतिरिक्त कुछ के साथ स्ट्रिंग के रूप में नहीं मानता है। आप जो भी मांगते हैं वह आपको मिलता है।

6

आपको ठीक से ठीक होने के लिए 5 वर्णों की आवश्यकता है। समाप्ति न्यूल एक के रूप में गिना जाता है, इसलिए यदि हमें एन अक्षरों की आवश्यकता है, तो एन + 1 आवंटित करें। या इसके विपरीत, एन के आवंटन के लिए आपके पास आपकी सामग्री के लिए एन -1 उपलब्ध है।

+0

मैंने उतना सोचा, लेकिन फिर यह मॉलोक के साथ क्यों काम करता है? – fresskoma

2

आप संभवतः 4 char से अधिक प्राप्त नहीं कर सकते हैं क्योंकि आपने अपने बफर में अधिकतम 4 बाइट्स के लिए केवल recv से पूछा है। आपको recv का रिटर्न वैल्यू देखना चाहिए ताकि यह देखने के लिए कि वास्तव में कितने बाइट्स लौटे थे।

मुझे संदेह है कि समस्या यह है कि आप उत्पादन को उत्पन्न करने वाले जो भी दिनचर्या से केवल 4 char एस आउटपुट के लिए सावधान नहीं हैं। संभावित रूप से गैर-शून्य समाप्त होने वाली प्रारंभिक सामग्री को प्रदर्शित करने का एक तरीका char बफर यह है।

printf("%.4s\n", buffer); 

एक पूरा recv कॉल टुकड़ा हो सकता है:

#define MAX_BUF_LEN (512) 
char buffer[MAX_BUF_LEN]; 
ssize_t count = recv(socket, buffer, MAX_BUF_LEN, 0); 

if (count > 0) 
    printf("%.*s\n", count, buffer); 
3

मुझे लगता अंतर एक संयोग है। जब आप एक स्ट्रिंग के रूप में बफर का उपयोग करते हैं, उदाहरण के लिए printf() में, इसे '0 0' मिलने तक इसकी सीमा से पहले पढ़ा जाएगा।

आपको दोनों मामलों में बफर [5] या मॉलोक (5) का उपयोग करना चाहिए। Memset() आवश्यक नहीं होना चाहिए, recv() के बाद एक बफर [4] = '\ 0' बेहतर रखना चाहिए।

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

  • कोई संबंधित समस्या नहीं^_^