2012-11-10 25 views
33

का उपयोग करें मैं थोड़ा समझता हूं कि memset() की परिभाषा क्या है। हालांकि, मुझे समझ में नहीं आता कि इसका क्या बिंदु है।मेमसेट परिभाषा और

परिभाषा: निर्दिष्ट मान पर पीआरटी द्वारा इंगित स्मृति के ब्लॉक के पहले अंक बाइट सेट करता है (एक हस्ताक्षरित चार के रूप में व्याख्या)।

तो क्या यह हार्ड कोड स्मृति पते में एक मान करता है?

memset(&serv_addr,0,sizeof(serv_addr) उदाहरण है कि मैं समझने की कोशिश कर रहा हूं।

क्या कोई व्यक्ति बहुत सरल तरीके से समझा सकता है?

+2

इसका उपयोग ज्यादातर structs और arrays प्रारंभ करने के लिए किया जाता है। – imreal

+0

तो यह सरणी [मूल्य] कहने जैसा है? ऐसा क्यों न करें, फिर मेमसेट का उपयोग करने का क्या मतलब है? –

+0

आप इसे 'सरणी [मान]' की तरह ही कर सकते हैं यदि आप संकलन समय के दौरान 'मान' के मान को जानते हैं (यह सी/सी ++ है)। – irrelephant

उत्तर

38

memset() एक अपेक्षाकृत सरल ऑपरेशन का एक बहुत तेजी से संस्करण है। यह उपरोक्त कार्यान्वयन की तुलना में यह बहुत तेज है।

+1

अजीब, आपके पास सी ++ प्रारंभकर्ता है लेकिन एक सी कास्ट है ... – Neil

+0

@Neil: अच्छा बिंदु - मैं एक सी ++ व्यक्ति हूं और मुझे एहसास हुआ कि मैं रूपांतरण पर भरोसा करता हूं। मैं कोड को सी और सी ++ दोनों में बदल दूंगा। –

+0

कोडेड के रूप में, आपके फ़ंक्शन में क्रियान्वयन परिभाषित व्यवहार है क्योंकि 'char'' char' प्रकार के लिए सीमा से बाहर हो सकता है। आपको इसके बजाय 'पी' को 'हस्ताक्षरित चार * पी = (हस्ताक्षरित चार *) बी के रूप में परिभाषित करना चाहिए;' (कलाकार केवल सी ++ में आवश्यक है)। – chqrlie

26

memset() आमतौर पर मूल्यों को आरंभ करने के लिए उपयोग किया जाता है। उदाहरण के लिए निम्नलिखित struct पर विचार करें:

struct Size { 
    int width; 
    int height; 
} 

तुम इतनी तरह ढेर पर इनमें से किसी एक बनाते हैं:

struct Size someSize; 

फिर उस struct में मानों अपरिभाषित जा करने के लिए जा रहे हैं। वे शून्य हो सकते हैं, वे तब भी हो सकते हैं जब स्टैक के उस हिस्से का आखिरी इस्तेमाल किया गया हो। तो आमतौर पर आप उस पंक्ति का पालन करेंगे:

memset(&someSize, 0, sizeof(someSize)); 

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

void* memset(void* b, int c, size_t len) { 
    char* p = (char*)b; 
    for (size_t i = 0; i != len; ++i) { 
     p[i] = c; 
    } 
    return b; 
} 

है, memset(b, c, l) मूल्य c को पता b पर शुरू l बाइट्स सेट:

+2

पूछे जाने वाले सवाल को देखते हुए कि मेमसेट का बिंदु क्या है, यह उत्तर स्वीकृत एक इमो से बेहतर है। –

3

मुझे लगता है कि serv_addr कुछ struct प्रकार के कुछ स्थानीय या वैश्विक चर struct sockaddr, शायद है - (या शायद एक class)।

&serv_addr उस चर का पता ले रहा है। यह एक वैध पता है, जिसे memset पर पहला तर्क दिया गया है। memset पर दूसरा तर्क बाइट (शून्य बाइट) भरने के लिए उपयोग किया जाने वाला बाइट है। memset का अंतिम तर्क उस मेमोरी जोन को भरने के लिए बाइट्स में आकार है, जो आपके उदाहरण में serv_addr चर का आकार है।

तो यह कॉल memset पर एक वैश्विक या स्थानीय चर serv_addr साफ़ करता है जिसमें कुछ struct शामिल हैं।

अभ्यास में, जीसीसी संकलक, जब यह अनुकूलन के है, चालाक कोड है कि के लिए उत्पन्न होगा, आमतौर पर unrolling और यह इनलाइन किए जाने वाले (वास्तव में, यह अक्सर अंतर्निहित है, इसलिए जीसीसी है इसके लिए बहुत चालाक कोड उत्पन्न कर सकते हैं)।

5

memset डेटा प्रकार के बावजूद स्मृति क्षेत्र को 0 पर सेट करने का एक आम तरीका है। कोई कह सकता है कि memset डेटा प्रकार की परवाह नहीं करता है और केवल सभी बाइट्स शून्य पर सेट करता है।

सी ++ में IMHO को memset करने से बचना चाहिए क्योंकि यह संभव है कि सी ++ प्रदान करने वाली प्रकार की सुरक्षा को रोकता है, इसके बजाय किसी को प्रारंभ करने के साधन के रूप में कन्स्ट्रक्टर या प्रारंभिकता का उपयोग करना चाहिए। कक्षा के उदाहरण पर किए गए मेमसेट कुछ अनजाने में भी नष्ट कर सकते हैं:

उदा।

class A 
{ 
public: 
    shared_ptr<char*> _p; 
}; 

का एक उदाहरण पर एक memset ऊपर एक संदर्भ काउंटर घटती ठीक से नहीं होता।

+1

यह उत्तर सूची में ऊपर होना चाहिए। सी ++ में मेमसेट का उपयोग करना सुरक्षित नहीं है। – mwm314

1

यह कुछ भी नहीं है लेकिन स्मृति को विशेष मान पर सेट करना है।

यहां उदाहरण कोड है।

मेमसेट (कॉन्स * पी, यूनिट 8_टी वी, यूनिट 8_टी एल), यहां पी स्मृति को लक्षित करने के लिए सूचक है, वी लक्ष्य बफर का मान है जो एक मान V और l पर सेट किया जाएगा डेटा।

while(L --> 0) 
{ 
    *p++ = V; 
} 
+0

ऑपरेटर '->' के लिए नीचे का अच्छा उदाहरण है, लेकिन मैं 'एल' तर्क के प्रकार के बारे में अत्यधिक संदेहजनक हूं:' unit8_t' 'size_t' होना चाहिए। – chqrlie

0

स्मृति में memset- सेट बाइट्स

Synopsis-

#include<string.h> 

शून्य * memset (शून्य * रों, पूर्णांक ग, size_t एन)

विवरण- memset () फ़ंक्शन एस द्वारा प्रतिस्थापित ऑब्जेक्ट के पहले एन बाइट्स में से प्रत्येक में सी (एक हस्ताक्षरित चार में परिवर्तित) की प्रतिलिपि बनायेगा। उपरोक्त फ़ंक्शन के लिए, मेमसेट() एस मान वापस कर देगा। क्यों memset

उपयोग करने के लिए हालांकि यहां कुछ ऐसा है जो मेरे साथ हुआ है -

+1

यह उत्तर 5 अन्य उत्तरों के साथ 4 साल की पुरानी पोस्ट में मूल्य कैसे जोड़ता है? –

+0

मैं एक उत्तर की तलाश में था और मुझे इस परिभाषा को किसी अन्य स्रोत से जानना पड़ा। इसलिए सोचा कि यह उन लोगों के लिए सहायक होगा जो इस की तलाश में हैं। – Ashit

0

मैं भी देख रहा हूँ।

मैंने strncpy (dest, स्रोत, वर्णों की संख्या) का उपयोग किया और कुछ गलत परिणाम प्राप्त कर रहे थे। हालांकि मुझे गंतव्य सरणी के आकार के बारे में निश्चित था।

इसलिए जब मैंने strncpy से पहले मेमसेट का उपयोग किया - मुझे strncpy आउटपुट के लिए बहुत अच्छे परिणाम मिल गए। मैं आगे की जांच और रिपोर्ट करूँगा।

+0

मुझे डर है कि यह उत्तर पूर्ण गैर-समझ में है: 'strncpy', जिसे आप कभी भी उपयोग करना चाहिए क्योंकि यह आपके द्वारा किए जाने वाले कार्यों को नहीं करता है, ** गंतव्य के सरणी को' '0'' के अंत में पैड करता है स्रोत स्ट्रिंग अगर कहा गया स्रोत स्ट्रिंग गंतव्य से छोटा है। हालांकि, यह स्रोत स्ट्रिंग बहुत लंबा होने पर ** ** गंतव्य को समाप्त नहीं करता है। 'Strncpy' पर कॉल करने से पहले' memset' का उपयोग करना कुछ भी नहीं बदलेगा। आपने आकार तर्क के लिए गलत मान पारित किया होगा, जैसे स्रोत स्ट्रिंग की लंबाई, जो एक सामान्य गलती है। – chqrlie

+0

टिप्पणी के लिए धन्यवाद। हम सबस्ट्रिंग दिनचर्या को नीचे लागू करने के लिए strncpy का उपयोग कर सकते हैं: strncpy (one_char_prod_arr [pcount], token.data.scalar.value, 1); one_char_prod_arr token.data.scalar.value –

+0

का पहला char प्राप्त करता है, मैं सलाह देता हूं कि इस या किसी भी उद्देश्य के लिए 'strncpy' का उपयोग न करें। आप स्ट्रिंग के एक हिस्से को निकालने के लिए 'memcpy() 'का उपयोग कर सकते हैं लेकिन सुनिश्चित करें कि आप मैन्युअल रूप से शून्य टर्मिनेटर जोड़ते हैं। – chqrlie