दिलचस्प पोस्ट
पायथन 2.6 में मैं एक थ्रेड सुरक्षित प्रिंट कैसे प्राप्त करूं? रिवर्स इंजीनियरिंग को एक डेटाबेस में नेविगेशन प्रॉपर्टी नामों में सुधार करें X86-64 लिनक्स में अब 32-बिट पूर्ण पते की इजाजत नहीं है? Jquery का उपयोग करके यादृच्छिक divs दिखाना गतिविधि से एंड्रॉइड में टुकड़े को डेटा भेजें एंड्रॉइड: एंड्रॉइड-पार्स में ईमेल क्लाइंट रिसीवर ईमेल आईडी खाली है एसक्यूएल सर्वर: मामला जब या उसके बाद => या समर्थित नहीं है MySQL सर्वर दूर चला गया – ठीक 60 सेकंड में कंपैटर-अवरोही क्रम (उपयोगकर्ता परिभाषित कक्षाएं) का उपयोग करके छंटनी क्या मैं फ़ील्ड 'datetime' या 'टाइमस्टैम्प' का उपयोग करूँ? प्रारंभिक त्रुटि में अपवाद छपाई यूटीएफ -8 स्ट्रिंग्स printf-wide vs. multibyte स्ट्रिंग literals सबसे नज़दीक वाली खिड़कियां क्या हैं (कांटा)? numpy सरणी असाइनमेंट समस्या मैं अपने ऐप से अनियंत्रित अपने ऐप से कैसे प्रवेश करूं? आईओएस

क्या मामलों में मैं malloc बनाम नया का उपयोग करता हूँ?

मैं सी ++ में देखता हूं कि आवंटन और मुफ्त डेटा के कई तरीके हैं और मैं समझता हूं कि जब आप कॉल करेंगे तो आप free कॉल कर सकते free और जब आप new ऑपरेटर का इस्तेमाल करते हैं, तो आपको delete साथ delete चाहिए और दो को मिक्स करने के लिए एक गलती है (जैसे कॉलिंग free() , जो कि new ऑपरेटर के साथ बनाया गया था) परन्तु मैं इस बात पर स्पष्ट नहीं हूं कि मुझे malloc / free का इस्तेमाल क्यों करना चाहिए और जब मुझे अपने वास्तविक विश्व कार्यक्रमों में new / delete चाहिए।

यदि आप एक सी ++ विशेषज्ञ हैं, तो कृपया मुझे इस बारे में नियम या नियमों के बारे में बताएं।

वेब के समाधान से एकत्रित समाधान "क्या मामलों में मैं malloc बनाम नया का उपयोग करता हूँ?"

जब तक आप सी का उपयोग करने के लिए मजबूर नहीं हैं , आपको कभी भी malloc उपयोग नहीं करना चाहिए हमेशा new उपयोग करें

यदि आपको डेटा का एक बड़ा हिस्सा चाहिए तो बस कुछ ऐसा करें:

 char *pBuffer = new char[1024]; 

सावधान रहें हालांकि यह सही नहीं है:

 //This is incorrect - may delete only one element, may corrupt the heap, or worse... delete pBuffer; 

डेटा की एक सरणी को हटाने के बजाय आपको यह करना चाहिए:

 //This deletes all items in the array delete[] pBuffer; 

new कीवर्ड ऐसा करने का सी ++ तरीका है, और यह सुनिश्चित करेगा कि आपके प्रकार के कन्स्ट्रक्टर का नाम होगाnew कीवर्ड भी अधिक प्रकार से सुरक्षित है जबकि malloc बिल्कुल प्रकार सुरक्षित नहीं है।

एकमात्र तरीका मैं सोच सकता था कि malloc का उपयोग करने के लिए फायदेमंद होगा यदि आपको अपने बफ़र के डेटा का आकार बदलने की आवश्यकता होगी new खोजशब्द के पास realloc जैसी समान तरह का नहीं है realloc फंक्शन आपके लिए स्मृति का एक हिस्सा अधिक कुशलतापूर्वक विस्तारित करने में सक्षम हो सकता है।

यह उल्लेख के लायक है कि आप new / free और malloc / delete मिश्रण नहीं कर सकते।

नोट: इस प्रश्न में कुछ जवाब अमान्य हैं I

 int* p_scalar = new int(5); // Does not create 5 elements, but initializes to 5 int* p_array = new int[5]; // Creates 5 elements 

संक्षेप में उत्तर है: ऐसा करने के लिए वास्तव में अच्छे कारण के बिना सी ++ के लिए malloc उपयोग न करें malloc में सी ++ के साथ उपयोग किए जाने वाले कई कमियां हैं, जो कि new को दूर करने के लिए परिभाषित किया गया था।

C ++ कोड के लिए नई द्वारा तय की गई कमी

  1. malloc किसी भी सार्थक तरीके से टाइप करना नहीं है सी ++ में आपको void* से वापसी की आवश्यकता है void* यह संभावित रूप से बहुत सी समस्याएं पेश करता है:

     #include <stdlib.h> struct foo { double d[5]; }; int main() { foo *f1 = malloc(1); // error, no cast foo *f2 = static_cast<foo*>(malloc(sizeof(foo))); foo *f3 = static_cast<foo*>(malloc(1)); // No error, bad } 
  2. यह उस से भी बदतर है। यदि प्रश्न के प्रकार पीओडी (सादे पुराने डेटा) है तो आप अर्ध समझदारी से इसके लिए स्मृति आवंटित करने के लिए malloc का उपयोग कर सकते हैं, क्योंकि पहले उदाहरण में f2 करता है

    यह इतना स्पष्ट नहीं है कि अगर पीओडी एक प्रकार है तथ्य यह है कि पीओडी से गैर-पीओडी के लिए किसी प्रकार की कोई भी परिणामी संकलक त्रुटि नहीं है और समस्याओं को डीबग करने में संभावित रूप से बहुत मुश्किल बदलना एक निश्चित प्रकार के लिए संभव है। उदाहरण के लिए, यदि कोई (संभवत: एक अन्य प्रोग्रामर, रखरखाव के दौरान, बहुत बाद में एक परिवर्तन करने के लिए होता है जिसके कारण foo अब पीओडी नहीं बनता था तो कोई भी स्पष्ट त्रुटि समय के संकलन में प्रकट नहीं होती जैसे आप उम्मीद करते हैं:

     struct foo { double d[5]; virtual ~foo() { } }; 

    f2 के malloc भी खराब हो जाएंगे, बिना किसी स्पष्ट निदान के। यहां का उदाहरण तुच्छ है, लेकिन संभव है कि गलती से गैर-पॉडिस को आगे बढ़ाना संभव है (उदाहरण के लिए एक आधार वर्ग में, गैर-पीओडी सदस्य जोड़कर) यदि आपके पास C ++ 11 / boost है तो आप यह जांचने के लिए is_pod का उपयोग कर सकते हैं कि यह धारणा सही है और यदि यह नहीं है तो त्रुटि उत्पन्न होती है:

     #include <type_traits> #include <stdlib.h> foo *safe_foo_malloc() { static_assert(std::is_pod<foo>::value, "foo must be POD"); return static_cast<foo*>(malloc(sizeof(foo))); } 

    यद्यपि बूस्ट को यह निर्धारित करने में असमर्थ है कि कोई प्रकार पीओडी बिना C ++ 11 या कुछ अन्य संकलक एक्सटेंशन

  3. अगर आवंटन विफल हो जाता है तो malloc वापस न लौटाता NULLnew std::bad_alloc फेंक देगा बाद में एक NULL सूचक का उपयोग करने का व्यवहार अपरिभाषित है। एक अपवाद साफ शब्दों में डाल दिया जाता है जब इसे फेंका जाता है और यह त्रुटि के स्रोत से फेंक दिया जाता है प्रत्येक कॉल पर उचित परीक्षण के साथ malloc को लपेटना कठिन और त्रुटि प्रवण लगता है। (आपको केवल एक बार भूलना होगा कि वह अच्छा काम वापस करने के लिए) एक अपवाद को एक स्तर पर प्रचारित करने की अनुमति दी जा सकती है जहां कॉलर इसे संसाधित रूप से संसाधित करने में सक्षम होता है, जहां के रूप में NULL को सार्थक ढंग से वापस करना कठिन होता है हम एक अपवाद फेंकने या प्रोग्राम से बाहर निकलने या कुछ हैंडलर को कॉल करने के लिए हमारे safe_foo_malloc फ़ंक्शन का विस्तार कर सकते हैं:

     #include <type_traits> #include <stdlib.h> void my_malloc_failed_handler(); foo *safe_foo_malloc() { static_assert(std::is_pod<foo>::value, "foo must be POD"); foo *mem = static_cast<foo*>(malloc(sizeof(foo))); if (!mem) { my_malloc_failed_handler(); // or throw ... } return mem; } 
  4. मौलिक रूप से malloc एक सी सुविधा है और new सी + + सुविधा है। नतीजतन, malloc कंस्ट्रक्शर्स के साथ अच्छी तरह से नहीं खेलता है, यह केवल बाइट्स का एक हिस्सा आवंटित करने पर ही दिखता है। हम अपना safe_foo_malloc आगे प्लेसमेंट का उपयोग करने के लिए बढ़ा सकते हैं:

     #include <stdlib.h> #include <new> void my_malloc_failed_handler(); foo *safe_foo_malloc() { void *mem = malloc(sizeof(foo)); if (!mem) { my_malloc_failed_handler(); // or throw ... } return new (mem)foo(); } 
  5. हमारे safe_foo_malloc फ़ंक्शन बहुत सामान्य नहीं है – आदर्श रूप में हम ऐसे कुछ चाहते हैं जो किसी भी प्रकार को नियंत्रित कर सकते हैं, न कि सिर्फ foo हम इसे गैर-डिफॉल्ट कन्स्ट्रक्टर के लिए टेम्पलेट्स और वैराडीक टेम्पलेट्स के साथ प्राप्त कर सकते हैं:

     #include <functional> #include <new> #include <stdlib.h> void my_malloc_failed_handler(); template <typename T> struct alloc { template <typename ...Args> static T *safe_malloc(Args&&... args) { void *mem = malloc(sizeof(T)); if (!mem) { my_malloc_failed_handler(); // or throw ... } return new (mem)T(std::forward(args)...); } }; 

    अब हालांकि सभी मुद्दों को ठीक करने में हमने अभी तक पहचान की है, हमने वास्तविक रूप से डिफॉल्ट new ऑपरेटर को फिर से बनाया है यदि आप malloc और प्लेसमेंट new का उपयोग करने जा रहे हैं तो आप भी साथ ही शुरू करने के लिए new उपयोग कर सकते हैं!

सी ++ एफक्यूए लाइट से :

[16.4] भरोसेमंद पुराने मॉलोक () के बजाय मुझे नये का उपयोग क्यों करना चाहिए?

पूछे जाने वाले प्रश्न: नया / हटाएं कन्स्ट्रक्टर / डिस्ट्रिक्टर को कॉल करें; नया प्रकार सुरक्षित है, मॉलोक नहीं है; एक वर्ग द्वारा नया ओवरराइड किया जा सकता है

एफक्यूए: एफएक्यू द्वारा उल्लिखित नए प्रश्नों के गुण अच्छे नहीं हैं, क्योंकि कन्स्ट्रक्टर, डिस्ट्रक्टर्स और ऑपरेटर ओवरलोडिंग कचरा हैं (देखें कि आपका कचरा संग्रह क्यों नहीं है?), और प्रकार सुरक्षा समस्या वास्तव में बहुत कम है (आमतौर पर आपके पास शून्य * डालने के लिए सही पॉइंटर प्रकार के लिए malloc द्वारा इसे टाइप किए गए पॉइंटर वैरिएबल को असाइन करने के लिए दिया गया, जो कि परेशान हो सकता है, लेकिन "असुरक्षित" से बहुत दूर)

ओह, और भरोसेमंद पुरानी मॉलोक का उपयोग करना समान विश्वसनीय और पुरानी रीहॉलक का उपयोग करना संभव बनाता है। बहुत बुरा है हमारे पास एक चमकदार नए ऑपरेटर का नवीनीकरण या कुछ नहीं है

फिर भी, नया एक भाषा में इस्तेमाल की जाने वाली आम शैली से विचलन को सही ठहराने के लिए पर्याप्त नहीं है, भले ही भाषा सी ++ है विशेष रूप से, गैर-तुच्छ कंसल्टेंट्स वाले वर्ग घातक तरीके से दुर्व्यवहार करेंगे यदि आप ऑब्जेक्ट्स को malloc करते हैं तो कोड भर में नए का उपयोग क्यों नहीं करें? लोग शायद ही कभी ऑपरेटर को अधिक अधिभार करते हैं, इसलिए यह संभवतः आपके रास्ते में बहुत ज्यादा नहीं मिलेगा। और अगर वे अधिभार नए करते हैं, तो आप हमेशा उन्हें रोकने के लिए कह सकते हैं

क्षमा करें, मैं बस विरोध नहीं कर सका 🙂

हमेशा सी ++ में नया उपयोग करें यदि आपको अनलिखित स्मृति के ब्लॉक की आवश्यकता है, तो आप ऑपरेटर को सीधे सीधे उपयोग कर सकते हैं:

 void *p = operator new(size); ... operator delete(p); 

malloc उपयोग करें और केवल स्मृति को आवंटित free लिए free सी-केंद्रित पुस्तकालयों और एपीआई द्वारा प्रबंधित किया जा रहा है। जो कुछ भी आप नियंत्रित करते हैं उसके लिए new और delete (और [] वेरिएंट का उपयोग करें)

नया बनाम मॉलोक ()

1) new एक ऑपरेटर है , जबकि malloc() एक फ़ंक्शन है

2) new कॉल कन्स्ट्रक्टर , जबकि malloc() नहीं करता है।

3) new रिटर्न सटीक डेटा प्रकार , जबकि malloc() शून्य * देता है

4) new कभी नल नहीं देता (विफलता पर फेंक देगा) जबकि malloc() नल रिटर्न देता है

5) मेमोरी का पुन: स्थान नियोजन new समय तक नहीं संभाला, जबकि malloc() कर सकते हैं

malloc और new बीच एक बड़ा अंतर है malloc स्मृति आवंटित करता है यह सी के लिए ठीक है, क्योंकि सी में स्मृति का एक ढेर एक वस्तु है।

सी ++ में, यदि आप पीओडी प्रकारों (जो कि सी प्रकार के समान हैं) से निपटने में नहीं हैं, तो आपको मेमोरी स्थान पर कन्स्ट्रक्टर को कॉल करना चाहिए, वास्तव में वहां एक ऑब्जेक्ट है। गैर-पीओडी प्रकार सी ++ में बहुत आम हैं, क्योंकि कई सी ++ फीचर्स एक ऑब्जेक्ट स्वचालित रूप से गैर-पीओडी बनाते हैं।

new स्मृति को आवंटित करता है और उस मेमोरी स्थान पर ऑब्जेक्ट बनाता है गैर-पीओडी प्रकारों के लिए इसका मतलब है कि कन्स्ट्रक्टर को फोन करना।

यदि आप ऐसा कुछ करते हैं:

 non_pod_type* p = (non_pod_type*) malloc(sizeof *p); 

आपके द्वारा प्राप्त संकेतक को संदर्भित नहीं किया जा सकता क्योंकि यह किसी ऑब्जेक्ट को इंगित नहीं करता है। इससे पहले कि आप इसे इस्तेमाल कर सकते हैं, आपको उस पर एक कन्स्ट्रक्टर को कॉल करने की आवश्यकता होगी (और यह नियुक्ति का new प्रयोग किया जाता है)

यदि, दूसरी तरफ, आप करते हैं:

 non_pod_type* p = new non_pod_type(); 

आपको एक पॉइंटर मिलता है जो हमेशा मान्य होता है, क्योंकि एक new ऑब्जेक्ट बनाया है।

यहां तक ​​कि पीओडी प्रकार के लिए, दोनों के बीच एक महत्वपूर्ण अंतर है:

 pod_type* p = (pod_type*) malloc(sizeof *p); std::cout << p->foo; 

कोड का यह भाग एक अनिर्दिष्ट मूल्य मुद्रित करेगा, क्योंकि malloc द्वारा बनाए गए पीओडी ऑब्जेक्ट प्रारंभ नहीं किए गए हैं

new साथ, आप कॉल करने के लिए एक निर्माता निर्दिष्ट कर सकते हैं, और इस प्रकार एक अच्छी तरह से परिभाषित मान प्राप्त कर सकते हैं।

 pod_type* p = new pod_type(); std::cout << p->foo; // prints 0 

यदि आप वाकई इसे चाहते हैं, तो आप बिना प्रारंभिक पीओडी वस्तुओं को प्राप्त करने के लिए new उपयोग कर सकते हैं। उस पर अधिक जानकारी के लिए यह अन्य उत्तर देखें

एक और अंतर विफलता पर व्यवहार है जब यह मेमोरी आवंटित करने में विफल रहता है, तो malloc एक रिक्त सूचक देता है, जबकि new एक अपवाद फेंकता है।

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

इन कारणों के लिए, C ++ कोड में आपको new उपयोग करना चाहिए, और नहीं malloc । लेकिन तब भी, आपको "खुले में" new उपयोग नहीं करना चाहिए, क्योंकि यह संसाधनों को प्राप्त करता है जिसे आपको बाद में रिलीज़ करने की आवश्यकता होती है। जब आप new उपयोग करते हैं, तो आपको तुरंत उसके परिणाम को एक संसाधन प्रबंधन वर्ग में पास करना चाहिए:

 std::unique_ptr<T> p = std::unique_ptr<T>(new T()); // this won't leak 

इसमें कुछ चीजें हैं जो new हैं जो malloc नहीं करता है:

  1. new उस ऑब्जेक्ट के कन्स्ट्रक्टर को कॉल करके ऑब्जेक्ट का निर्माण करता है
  2. new आवंटित मेमोरी के टाइपकास्टिंग की आवश्यकता नहीं है
  3. इसके लिए आवंटित होने वाली स्मृति की आवश्यकता नहीं होती है, बल्कि इसे निर्माण करने के लिए कई ऑब्जेक्ट की आवश्यकता होती है।

इसलिए, यदि आप malloc उपयोग करते हैं, तो आपको स्पष्ट रूप से ऊपर की बातें करने की आवश्यकता होती है, जो हमेशा व्यावहारिक नहीं होता है। इसके अतिरिक्त, new ओवरलोड किया जा सकता है लेकिन malloc नहीं हो सकता।

आपके प्रश्न का उत्तर देने के लिए, आपको malloc और new बीच का अंतर पता होना चाहिए। अंतर सरल है:

malloc मेमोरी आवंटित करता है , जबकि new मेमोरी को आवंटित करता है और उस ऑब्जेक्ट के कन्स्ट्रक्टर को कॉल करता है जिसे आप स्मृति के लिए आवंटित कर रहे हैं

इसलिए, जब तक कि आप सी तक ही सीमित न हों, आपको कभी भी मॉलोक का उपयोग नहीं करना चाहिए, खासकर जब C ++ ऑब्जेक्ट्स के साथ व्यवहार करते हैं यह आपके कार्यक्रम को तोड़ने के लिए एक नुस्खा होगा।

इसके अलावा free और delete बीच अंतर काफी समान है। अंतर यह है कि delete से आपके ऑब्जेक्ट के नाशक को स्मृति मुक्त करने के अलावा कॉल किया जाएगा।

अगर आप c ++ का उपयोग कर रहे हैं तो मॉलोक / कॉलोक के बजाय नए / हटाए जाने का प्रयास करें, क्योंकि वे ऑपरेटर हैं, उनके लिए malloc / calloc की तुलना में आप उस के लिए एक और हेडर शामिल करते थे। इसलिए एकल कोडिंग में दो अलग-अलग भाषाओं को मिश्रण नहीं करते । उनका काम हर तरह से समान है, दोनों में हंस तालिका में डायरेमिक रूप से मेमोरी से मेमोरी आवंटित करता है।

यदि आपके पास सी कोड है जो आप को सी ++ पर बंद करना चाहते हैं, तो आप उसमें कोई भी malloc () कॉल छोड़ सकते हैं किसी भी नए C ++ कोड के लिए, मैं इसके बजाय नए का उपयोग करने की सलाह देता था।

यदि आप उस डेटा के साथ काम करते हैं जिसके लिए निर्माण / विनाश की आवश्यकता नहीं होती है और पुनर्वितरण की आवश्यकता होती है (उदाहरण के लिए, बड़ी मात्रा में ints), तो मेरा मानना ​​है कि malloc / मुक्त एक अच्छा विकल्प है क्योंकि यह आपको realloc देता है, जो नए- memcpy से तेज़ तरीका है -निर्दिष्ट (यह मेरे लिनक्स बॉक्स पर है, लेकिन मुझे लगता है कि यह प्लेटफॉर्म निर्भर हो सकता है)। यदि आप सी ++ ऑब्जेक्ट्स के साथ काम करते हैं जो पीओडी नहीं हैं और निर्माण / विनाश की आवश्यकता है, तो आपको नए और डिलीट ऑपरेटर का उपयोग करना चाहिए।

वैसे भी, मुझे नहीं पता है कि आपको दोनों का उपयोग क्यों नहीं करना चाहिए (बशर्ते कि आप अपनी मॉलोकेड मेमोरी को मुक्त करें और नए के साथ आबंटित ऑब्जेक्ट्स को हटा दें) अगर गति को बढ़ावा देने का लाभ ले सकते हैं (कभी-कभी एक महत्वपूर्ण बात, अगर आप बड़े सरणियों को पुनः लोड करते हैं पीओडी के) कि realloc आप दे सकते हैं।

जब तक आपको इसकी ज़रूरत नहीं है, आपको सी ++ में नया होना चाहिए / हटा देना चाहिए

निचले परिप्रेक्ष्य से, नई मेमोरी देने से पहले नई मेमोरी की सभी मेमोरी शुरू हो जाएगी, मॉलोक स्मृति की मूल सामग्री को बनाए रखेगा।

new संरचना के मूलभूत मूल्यों को आरम्भ किया जाएगा और इसके संदर्भ में सही तरीके से उसमें संदर्भ जोड़ देगा।

उदाहरण के लिए

 struct test_s { int some_strange_name = 1; int &easy = some_strange_name; } 

इसलिए new struct test_s कार्य संदर्भ के साथ एक प्रारंभिक संरचना वापस करेगा, जबकि malloc'ed संस्करण में कोई डिफ़ॉल्ट मान नहीं है और आंतरिक संदर्भ प्रारंभ नहीं किए जाते हैं।

new और delete ऑपरेटर वर्गों और संरचनाओं पर काम कर सकते हैं, जबकि malloc और free केवल मेमोरी के ब्लॉकों के साथ कार्य करता है, जिसे डाली जाने की आवश्यकता है।

new/delete का उपयोग करना आपके कोड को बेहतर बनाने में मदद करेगा क्योंकि आपको आवंटित स्मृति को आवश्यक डेटा संरचना में डालने की आवश्यकता नहीं होगी।

रिलायको का इस्तेमाल करते हुए अपने आवंटन और फिर पुनः आवंटन (साधारण पॉड प्रकार, ऑब्जेक्ट्स नहीं) के रूप में कन्वर्ट करने के बजाय नए / डिलीट के बजाय मॉलोक / फ्री का उपयोग करने पर विचार करने के लिए दुर्लभ मामला है क्योंकि सी ++ में रीलॉक के समान फ़ंक्शन नहीं है (यद्यपि इसे अधिक सी ++ का उपयोग करके किया जा सकता है दृष्टिकोण)

निम्नलिखित परिदृश्य में, हम नए का उपयोग नहीं कर सकते क्योंकि यह कन्स्ट्रक्टर कॉल करता है।

 class B { private: B *ptr; int x; public: B(int n) { cout<<"B: ctr"<<endl; //ptr = new B; //keep calling ctr, result is segmentation fault ptr = (B *)malloc(sizeof(B)); x = n; ptr->x = n + 10; } ~B() { //delete ptr; free(ptr); cout<<"B: dtr"<<endl; } }; 

malloc () को गतिशील रूप से सी में स्मृति असाइन करने के लिए उपयोग किया जाता है जबकि सी ++ में समान कार्य नई () द्वारा किया जाता है तो आप 2 भाषाओं के कोडन सम्मेलनों को मिक्स नहीं कर सकते यह अच्छा होगा यदि आप कॉलोक और मॉलोक () के बीच अंतर के लिए पूछा