2010-08-13 14 views
35

मैं हमेशा इस बारे में उत्सुक रहा हूं - सी ++ में मुझे malloc से वापसी मूल्य क्यों डालना है, लेकिन सी में नहीं? यहाँसी ++ को malloc() के लिए एक कास्ट की आवश्यकता क्यों है लेकिन सी नहीं है?

int *int_ptr = (int *)malloc(sizeof(int*)); 

और सी ++ में उदाहरण है कि काम नहीं करता है (कोई डाली) है:

यहाँ सी में उदाहरण ++ कि काम करता है

int *int_ptr = malloc(sizeof(int*)); 

मैंने सुना है कि सी में, वास्तव में, malloc() से आउटपुट कास्टिंग एक गलती है।

क्या कोई इस विषय पर टिप्पणी कर सकता है?

+0

सी ++ अधिक प्रकार के संवेदनशील होने के कारण आपको एक कास्ट के माध्यम से सटीक प्रकार निर्दिष्ट करने की आवश्यकता होती है। – Abhay

+9

यह सीधे आपके प्रश्न से संबंधित नहीं है, लेकिन मुझे लगता है कि आप 'sizeof (int) ',' sizeof (int *)' नहीं चाहते हैं। उस ने कहा, 'sizeof * int_ptr' का उपयोग करना बेहतर है, जो गारंटी देता है कि आप जो भी प्रकार' int_ptr' इंगित करते हैं, उसके लिए आप सही मात्रा में स्मृति आवंटित करेंगे। – bcat

+5

आप सी ++ में मॉलोक का उपयोग क्यों करेंगे? – SoapBox

उत्तर

27

कई अंक:

सी शून्य संकेत परोक्ष किसी अन्य वस्तु सूचक प्रकार में परिवर्तित हो सकते हैं। सी ++ नहीं करता है।

सी में malloc() के परिणाम कास्टिंग करना उपयोगी डायग्नोस्टिक को दबाएगा यदि आप stdlib.h शामिल करना भूल जाते हैं या अन्यथा malloc() के दायरे में कोई घोषणा नहीं है। याद रखें कि यदि सी पूर्व घोषणा के बिना फ़ंक्शन कॉल देखता है, तो यह मान लेगा कि फ़ंक्शन int देता है। यदि आपके पास malloc() के लिए कोई घोषणा नहीं है और आप कास्ट छोड़ देते हैं, तो आपको असंगत प्रकार (सूचक से int) असाइन करने की कोशिश कर रहे प्रभाव के लिए निदान मिलेगा। यदि आप परिणाम डालते हैं, तो आप डायग्नोस्टिक को दबाते हैं और संभावित रूप से रनटाइम समस्याएं होती हैं, क्योंकि इसकी गारंटी नहीं है कि एक सूचक मूल्य को एक int में वापस और फिर एक पॉइंटर में परिवर्तित करने से आपको एक उपयोगी परिणाम मिल जाएगा।

यदि आप सी ++ लिख रहे हैं, तो आपको malloc() और free() के बजाय new और delete का उपयोग करना चाहिए।हाँ, हाँ, हाँ, मैंने सभी कारणों को सुना है कि क्यों लोग अपने कोड को सी और सी ++ दोनों के रूप में संकलित करना चाहते हैं, लेकिन भाषा के लिए सही स्मृति प्रबंधन उपकरण का उपयोग करने के लाभ दो संस्करणों को बनाए रखने की लागत से अधिक हैं।

नोट: void * प्रकार C89 मानक में जोड़ा गया था; सी के पहले संस्करणों में malloc() वापसी char * थी, इसलिए उन संस्करणों में आवश्यक था यदि आप परिणाम को एक अलग सूचक प्रकार के लिए निर्दिष्ट कर रहे थे। लगभग हर कोई कम से कम C89 मानक का समर्थन करता है, इसलिए आपके पुराने कार्यान्वयन में से एक में चलने की बाधा बहुत कम है।

+4

कोई आधुनिक कंपाइलर आउटपुट कास्टिंग के बावजूद, मॉलोक() की अनुपलब्ध घोषणा के लिए चेतावनी नहीं देगा? –

+0

@ डैनियल: यह भी आपके चेतावनी स्तर पर निर्भर करता है। कास्ट चेतावनी आम तौर पर गायब घोषणा की तुलना में कम चेतावनी स्तर में दिखाई देती है। –

+0

शायद, लेकिन फिर भी कास्ट छोड़ने के लिए यह अभी भी सबसे अच्छा अभ्यास है। –

7

सी void* से अन्य सूचक प्रकारों के लिए निहित कास्ट का समर्थन करता है। सी ++ इसे अस्वीकार करता है।

एक कारण यह है कि यह सी में पर स्पष्ट रूप से malloc के रिटर्न मान कास्ट करने के लिए सिकोड़ी है कि अगर malloc हस्ताक्षर वर्तमान संकलन इकाई में शामिल नहीं है, संकलक समझेंगे कि वापसी प्रकार int और यह अंतर्निहित रूपांतरण है पॉइंटर प्रकार के लिए आप एक संकलन-समय चेतावनी में परिणाम देने के लिए असाइन कर रहे हैं जिसे आप तुरंत हल करेंगे। एक स्पष्ट कलाकार के साथ, यदि आप यह गलती करते हैं, तो कोई चेतावनी जारी नहीं की जाएगी।

13

ऐसा इसलिए है क्योंकि सी ++ दृढ़ता से टाइप की गई भाषा है। सी ++ में, निहित कास्ट केवल तभी अनुमति दी जाती है जब वे "चौड़े" हों, यानी, यदि नया प्रकार पुराना प्रकार धारण कर सकने वाले प्रत्येक मूल्य को पकड़ सकता है। एक छोटे पूर्णांक प्रकार से एक बड़े पूर्णांक प्रकार में कास्टिंग की अनुमति है; किसी भी सूचक प्रकार से कास्टिंग void* की अनुमति है; एक उपclass से अपने superclass करने के लिए कास्टिंग की अनुमति है। अन्य सभी जानवरों को स्पष्ट रूप से बनाया जाना चाहिए, जिससे संकलक को बताया जा रहा है "मुझे पता है कि मैं क्या कर रहा हूं, यह कोई गलती नहीं है"।

malloc()void* देता है, जो कुछ भी हो सकता है, इसलिए संकलक गारंटी नहीं दे सकता कि आपकी कास्ट सफल हो जाएगी (या सार्थक हो)। एक स्पष्ट कलाकार का उपयोग करके, आप संकलक को बता रहे हैं कि आप जो कर रहे हैं वह वास्तव में जानबूझकर है।

सी, ओटीओएच, ऐसे कठोर कास्टिंग नियम नहीं हैं; आप खुशी से किसी भी दो प्रकार के बीच कास्ट कर सकते हैं, और आप प्रोग्रामर के रूप में यह सुनिश्चित करने के लिए ज़िम्मेदार हैं कि परिणामस्वरूप कोई बुरी चीजें नहीं होती हैं।

+6

मैं बिना किसी समस्या के 'int'' bool' डाल सकता हूं। – UncleBens

+0

* "ऐसा इसलिए है क्योंकि सी ++ दृढ़ता से टाइप की गई भाषा है।" * ... और सी नहीं है !? – cdhowie

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