2016-01-15 9 views
7

::operator new(size_t) आंतरिक रूप से malloc() पर कॉल करें, या क्या यह सिस्टम कॉल/ओएस-विशिष्ट लाइब्रेरी कॉल का सीधे उपयोग करता है? सी ++ मानक क्या कहता है?क्या :: ऑपरेटर नया (size_t) malloc() का उपयोग करता है?

this answer में यह कहा गया है कि:

malloc() एक पते किसी भी मानक प्रकार के लिए गठबंधन वापस जाने के लिए गारंटी है। ::operator new(n) केवल n से बड़े किसी भी मानक प्रकार के लिए गठित पते को वापस करने की गारंटी नहीं है, और यदि T कोई वर्ण प्रकार नहीं है तो नया T[n] केवल T के लिए गठित एक पता वापस करने की आवश्यकता है।

और यह बताता है कि new() को malloc() पर कॉल करने की आवश्यकता नहीं हो सकती है।

नोट: आवंटन की तुलना में अन्य सब कुछ के बारे में SO question है।

+0

डुप्ले/संबंधित: http://stackoverflow.com/questions/377178/how-does-the- मानक- नया- ऑपरेटर-work-in-c – NathanOliver

+0

इसी तरह का सवाल है: क्या पॉइंटर को आवंटित करना संभव है ' 'हटाएं' के बजाय 'मुक्त') के साथ नया 'कीवर्ड'। – i486

+0

@NathanOliver: मेरा संपादन देखें। उस प्रश्न का शीर्षक बताता है कि यह एक डुप्ली है, इसकी सामग्री अन्यथा सुझाती है। – einpoklum

उत्तर

8

कैसे operator new कार्यान्वित किया जाता है के विवरण मानक पुस्तकालय की एक विशेष कार्यान्वयन की संपत्ति हैं - यहां तक ​​कि नहीं एक कंपाइलर या ऑपरेशन सिस्टम। मैं एक (gnu) से परिचित हूं और 3 अन्य लोगों के बारे में जानता हूं - क्लांग, अपाचे और एमएसएफटी। वे सभी malloc()operator new के भीतर उपयोग कर रहे हैं, क्योंकि यह लाइब्रेरी डेवलपर का जीवन इतना आसान बनाता है।

यदि malloc() का उपयोग नहीं किया गया था, तो डेवलपर को स्मृति आवंटन के मामले में बहुत कुछ लागू करना होगा, और वास्तव में स्मृति का अनुरोध करने के लिए ओएस-निर्भर तर्क के साथ कोड को छिड़कना होगा। कोई भी ऐसा नहीं करना चाहता है जब malloc() पहले से मौजूद है। लेकिन इसका कोई मतलब नहीं है कि वे इसका इस्तेमाल करने के लिए बाध्य हैं।

2

हां, यह मॉलोक को कॉल कर सकता है - वीएस और मानक रनटाइम लाइब्रेरी के साथ विंडोज़ के तहत यह malloc पर कॉल करता है।

आपको नए ऑपरेटर को अधिभारित करने और अपने आवंटन समारोह को कॉल करने की अनुमति है। आवेदन में मैं काम करता हूं, हमारे पास डॉग ली से कस्टम मैलोक है जिसमें एम्बेडेड सिस्टम के लिए कई अनुकूलन हैं। विंडोज मॉलोक को कॉल करता है क्योंकि यह हेपअलोक को कॉल करता है, जो विंडोज़ के तहत मानक ढेर आवंटन समारोह है। यह CrtDbg api के साथ आवंटन त्रुटियों को डीबग करने की भी अनुमति देता है। पाश के भीतर, को समारोह पहला प्रयास का अनुरोध भंडारण आवंटन:

जवाब और अधिक औपचारिक मैं मानक ऊपर देखा है और §18.6.1.1 में, मैंने पाया कि new

एक पाश पर क्रियान्वित करने के लिये । चाहे प्रयास में पर कॉल शामिल है, मानक सी लाइब्रेरी फ़ंक्शन malloc को निर्दिष्ट नहीं किया गया है

इसलिए wheteher malloc का उपयोग अनिर्दिष्ट है - यह इसका उपयोग कर सकता है या नहीं।

+0

और _must_ इसे मॉलोक कहते हैं? – einpoklum

+1

@inpoklum, ज़ाहिर नहीं है। यह कार्यान्वयन विस्तार है। इसके अलावा, उत्तर तकनीकी रूप से सही नहीं है - यह महत्वपूर्ण है कि आप किस मानक पुस्तकालय का उपयोग करते हैं, न कि संकलक या ओएस। हालांकि, यह किसी भी लाइब्रेरी कार्यान्वयन के लिए आपके स्वयं के ओएस-विशिष्ट कोडिंग करने के बजाय, malloc() की पहले से उपलब्ध कार्यक्षमता का पुन: उपयोग करने के लिए समझ में आता है। – SergeyA

+0

@ सर्गेय: तकनीकी रूप से, "कार्यान्वयन" के बारे में मानक वार्ता। यदि आप एक स्थान से एक कंपाइलर और दूसरे से मानक पुस्तकालय और तीसरे से एक लिंकर लेकर अपना स्वयं का कार्यान्वयन बनाते हैं, तो आप इसे लागू करने के लिए एक कार्यान्वयनकर्ता और जिम्मेदार होते हैं। अधिकांश लोगों को एक ही स्रोत से अपना कार्यान्वयन मिलता है (और इसे "एक कंपाइलर" कहते हैं)। –

3

यह आमतौर पर कर सकता है।
Windows पर (अधिक विशिष्ट रूप से कुलपति पर ++), कॉल की श्रृंखला

तरह

operator new कॉल malloc कॉल HeapAlloc

HeapAlloc विशिष्ट ढेर से स्मृति आवंटित करने के लिए एक Windows API कार्य है लग रहा है। जब प्रक्रिया बढ़ जाती है, तो यह एक ढेर आवंटित करता है (सीआरटी ढेर) जिसमें सभी मानक आवंटन स्मृति लेता है।

नहीं, यह मॉलोक को कॉल करने के लिए बाध्य नहीं है। यह लाइब्रेरी डेवलपर्स/एंड यूजर डेवलपर पर निर्भर करता है कि वे कहां से अपनी याददाश्त चाहते हैं।

उदाहरण के लिए, मैं एक मोनो-थ्रेडेड प्रोग्राम बना सकता हूं। ढेर पर घातक दौड़-स्थिति को रोकने के लिए आमतौर पर ढेर आवंटक ढेर ताला लगा देता है जब आवंटन/विलोपन होता है। लेकिन यदि मेरा प्रोग्राम मोनोथ्रेड किया गया है, तो मुझे समस्या नहीं है।
मैं WinApi HeapCreate के साथ अपना खुद का ढेर बनाना चुन सकता हूं और HEAP_NO_SERIALIZE पास कर सकता हूं जो ढेर को लॉक छोड़ देता है। तो मैं सादा HeapAlloc के साथ operator new का उपयोग कर सकता हूं। यह एक ऐसा मामला है जहां मैं new विभिन्न फ़ंक्शन के साथ काम कर सकता हूं तो malloc

एक और निम्न स्तर का दृष्टिकोण जो कभी-कभी * किया जाता है, VirtualAlloc के साथ विशाल मेमोरी ब्लॉक आवंटित करना है, फिर किसी भी समय new पर कॉल करने के बाद फिर से गणना की गई स्मृति पता पास करें।

(इन approches के सभी बहुत शायद ही कभी किया जाता है, और मेरे experiance से वे निष्पादन समय के लिए कम से कम improvment लाने)

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