2010-05-15 4 views

उत्तर

32

वहाँ सी

में कोई new/delete अभिव्यक्ति निकटतम बराबर malloc and free functions कर रहे हैं, अगर आप कंस्ट्रक्टर्स/विनाशकर्ता और प्रकार सुरक्षा की अनदेखी है।

#include <stdlib.h> 

int* p = malloc(sizeof(*p)); // int* p = new int; 
... 
free(p);      // delete p; 

int* a = malloc(12*sizeof(*a)); // int* a = new int[12]; 
... 
free(a);       // delete[] a; 
+2

* @ KennyTM: * क्या 'sizeof (* पी)' वास्तव में 'p' भिन्नता है, या यह पूरी तरह से लेखन के बराबर है' sizeof (int) '? ऐसा लगता है कि पूर्व मामले में, यह अभिव्यक्ति संभावित रूप से सेगमेंटेशन गलती का कारण बनती है (क्योंकि 'p' अभी तक इस बिंदु पर असाइन नहीं किया गया है)। बाद के मामले में, मैं शायद अभी भी 'sizeof (int)' लिखना पसंद करूंगा क्योंकि इस कथन के बारे में गलतफहमी के लिए कम संभावना है। – stakx

+5

@stakx: 'sizeof' ऑपरेटर का संकलन समय पर मूल्यांकन किया जाता है। कोई dereferencing नहीं है। 'sizeof (* p)' को 'sizeof (int)' के लिए प्राथमिकता दी जाती है क्योंकि यदि आप 'p' के प्रकार को 'डबल' में बदलते हैं तो कंपाइलर आपको आकार मिलान के बारे में चेतावनी नहीं दे सकता है। – kennytm

+8

@stakx 'sizeof' ऑपरेटर ** टाइप ** से' size_t' तक मैपिंग है। इसके ऑपरेंड का ** मूल्य ** बिल्कुल दिलचस्प नहीं है। उदाहरण के लिए, 'आकार (1 + 2)' में, परिणाम '3' की गणना करने की बिल्कुल आवश्यकता नहीं है। 'Sizeof' ऑपरेटर बस' int + int' प्रकार की अभिव्यक्ति को देखता है और अनुमान लगाता है कि परिणाम भी 'int' है। फिर यह 'int' से 4 (या 2 या 8, प्लेटफार्म के आधार पर) को मानचित्र करता है। यह 'आकार (* पी) 'के साथ एक ही बात है। प्रकार प्रणाली जानता है कि, प्रकार के स्तर पर, 'int *' को संदर्भित करने से 'int 'उत्पन्न होता है। 'sizeof' को' * p' के मान में कोई दिलचस्पी नहीं है, केवल प्रकार के मामले हैं। – fredoverflow

3

सीधे एक सटीक प्रतिकृति नहीं बल्कि संगत समकक्ष मॉलोक और मुक्त हैं।

<data-type>* variable = (<data-type> *) malloc(memory-size); 
free(variable); 

नहीं कंस्ट्रक्टर्स/विनाशकर्ता - वैसे भी उन्हें सी नहीं है :)

स्मृति आकार पाने के लिए आपको sizeof ऑपरेटर का उपयोग कर सकते हैं।

आप बहुआयामी सरणियों के साथ काम करना चाहते हैं, तो आप इसे कई बार (नया) की तरह उपयोग करने के लिए की आवश्यकता होगी:

int** ptr_to_ptr = (int **) malloc(12 * sizeof(int *)); //assuming an array with length 12. 
ptr[0] = (int *) malloc(10 * sizeof(int)); //1st element is an array of 10 items 
ptr[1] = (int *) malloc(5 * sizeof(int)); //2nd element an array of 5 elements etc 
+4

सी में आपको शून्य से * अन्य पॉइंटर्स तक कास्ट करने की आवश्यकता नहीं है। इसका सिर्फ int * p = malloc (sizeof (int) * cElements); –

+0

क्रिस: क्या आप निश्चित हैं? मैंने कुछ समय से सी के साथ काम नहीं किया है, लेकिन आईआईआरसी, मुझे ऐसा करना था क्योंकि वापसी का प्रकार मॉलोक शून्य है *। –

+0

सी 'शून्य * में स्वचालित रूप से अन्य सूचक प्रकारों में परिवर्तित हो जाता है। मॉलोक की वापसी कास्टिंग त्रुटियों का कारण बन सकता है यदि आपने 'stdlib.h' शामिल नहीं किया है, क्योंकि पैरामीटर को 'int' माना जाएगा। –

2

उपयोग malloc/मुक्त कार्य करता है।

6

ध्यान दें कि निर्माता सी ++ में अपवाद फेंक सकते हैं। player* p = new player(); के बराबर, सी

struct player *p = malloc(sizeof *p); 
if (!p) handle_out_of_memory(); 
int err = construct_player(p); 
if (err) 
{ 
    free(p); 
    handle_constructor_error(); 
} 

delete p के बराबर सरल है में कुछ इस तरह होगा क्योंकि विनाशकर्ता कभी नहीं करना चाहिए "फेंक"। सी ++ में new और delete की

destruct(p); 
free(p); 
+0

'construct_player' जैसा दिखता है? –

5

उपयोग दो जिम्मेदारी को जोड़ती है - आवंटन/गतिशील स्मृति को रिहा, और initialising/एक वस्तु को रिहा।

जैसा कि अन्य सभी उत्तरों कहते हैं, गतिशील स्मृति आवंटित करने और रिलीज़ करने का सबसे आम तरीका malloc और free पर कॉल कर रहा है। आप स्मृति का एक बड़ा हिस्सा प्राप्त करने के लिए ओएस-विशिष्ट कार्यों का भी उपयोग कर सकते हैं और उसमें अपनी ऑब्जेक्ट आवंटित कर सकते हैं, लेकिन यह दुर्लभ है - केवल तभी यदि आपके पास पर्याप्त विशिष्ट आवश्यकताएं हैं जो मॉलोक संतुष्ट नहीं होती है।

सी में, अधिकांश एपीआई कार्यों की एक जोड़ी प्रदान करेंगे जो new और delete की अन्य भूमिकाओं को पूरा करती है।

// C++ 
fstream* fp = new fstream("c:\\test.txt", "r"); 
delete fp; 

// C 
FILE *fp=fopen("c:\\test.txt", "r"); 
fclose(fp); 

हो सकता है कि fopenmalloc का उपयोग करता FILE struct के लिए भंडारण आवंटित करने के लिए है, या यह स्थिर के लिए एक मेज का आवंटन हो सकता है:

उदाहरण के लिए, फ़ाइल एपीआई खुले और बंद कार्यों की एक जोड़ी का उपयोग करता है प्रक्रिया शुरू होने पर फ़ाइल पॉइंटर्स की अधिकतम संख्या। मुद्दा यह है कि एपीआई को क्लाइंट को malloc और free का उपयोग करने की आवश्यकता नहीं है।

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

pthread_t thread; 

pthread_create(&thread, NULL, thread_function, (void*) param); 

इस ग्राहक अधिक लचीलापन देता है, लेकिन पुस्तकालय और ग्राहक के बीच युग्मन बढ़ जाती है - ग्राहक, pthread_t प्रकार के आकार का पता करने की जरूरत है, जबकि अगर पुस्तकालय दोनों संभालती है आवंटन और प्रारंभिकरण क्लाइंट को प्रकार के आकार को जानने की आवश्यकता नहीं है, इसलिए कार्यान्वयन क्लाइंट को बदलने के बिना भिन्न हो सकता है। क्लाइंट के बीच उतना ही युग्मन और सी ++ के कार्यान्वयन के रूप में कार्यान्वयन नहीं करता है। (यह सी के बारे में सोचना अक्सर बेहतर है ++ एक OO भाषा से vtables के साथ एक टेम्पलेट metaprogramming भाषा के रूप में)

+0

क्या आप स्पष्ट रूप से समझा सकते हैं कि मॉलोक किस विशिष्ट आवश्यकताओं को पूरा नहीं करता है? – Pacerier

+0

@Pacerier 'malloc' स्मृति आवंटित करता है। 'ऑपरेटर नया' (आमतौर पर) स्मृति आवंटित करता है * और * निर्दिष्ट वस्तु के वर्ग के निर्माता द्वारा प्रदान किए गए मानों को शामिल करने के लिए स्मृति को प्रारंभ करता है। ('ऑपरेटर न्यू' नामक 'ऑपरेटर न्यू' का एक चर है जिसे 'प्लेसमेंट न्यू' कहा जाता है जो स्मृति आवंटित नहीं करता है, इसलिए आप पहले भाग के लिए मॉलोक का उपयोग कर सकते हैं, और यदि आप चाहें तो दूसरे के लिए नया उपयोग कर सकते हैं) –

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