2010-07-01 12 views
11

मुझे लगता है कि लोगों को अक्सर लिखने सी कोड जैसे:सी में मॉलोक (256) और मॉलोक (आकार (चार) * 256) बराबर हैं?

char *ptr = malloc(sizeof(char)*256); 

वास्तव में जरूरी है कि है? मानक का कहना है कि sizeof(char)==1 परिभाषा के द्वारा, तो यह मतलब नहीं है बस लिखने के लिए:

char *ptr = malloc(256); 

धन्यवाद, बोडा Cydo।

+1

देखें: http://stackoverflow.com/questions/2215445/are-there-machines-where-sizeofchar-1 – Saul

+2

यह भी ध्यान देने योग्य है कि आकार() ऑपरेटर का संकलन समय पर मूल्यांकन किया जाता है, इसलिए कोई रनटाइम प्रदर्शन नहीं होता है sizeof() का उपयोग करने के लिए हिट करें। (उस मामले को छोड़कर जहां सरणी की लंबाई रनटाइम पर निर्दिष्ट होती है, लेकिन यह वह उदाहरण नहीं है जिसका उपयोग आपने किया था।) – poundifdef

+0

कॉलोक क्यों नहीं? – luiscubal

उत्तर

21

हां, सी sizeof(char) को 1, हमेशा (और सी ++ भी करता है) परिभाषित करता है।

बहरहाल, एक सामान्य नियम के रूप में, मैं की तरह कुछ सलाह देंगे:

char *ptr = malloc(256 * sizeof(*ptr)); 

इस तरह, जब अपने मालिक का कहना है की तरह कुछ: "ओह, BTW हम सिर्फ चीन से एक आदेश मिला तो हम करने की जरूरत है यथाशीघ्र सभी तीन चीनी अक्षर संभाल ", आप इसे करने के लिए बदल सकते हैं:

wchar_t *ptr // ... 

और बाकी ही रह सकते हैं। यह देखते हुए कि आपके पास लगभग 10 मिलियन सिरदर्द होने की कोशिश कर रहे हैं I18n को आधा रास्ते भी संभालने की कोशिश कर रहे हैं, कुछ को भी समाप्त करना सार्थक है। यह, ज़ाहिर है, सामान्य मामला मानता है कि आपके char एस वास्तव में पात्रों को पकड़ने का इरादा रखते हैं - यदि यह किसी प्रकार का कच्चा बफर है, और आप वास्तव में 256 बाइट स्टोरेज चाहते हैं, भले ही कितने (कुछ) वर्ण हो सकता है, आपको शायद malloc(256) के साथ रहना चाहिए और इसके साथ किया जाना चाहिए।

+0

हू यह चालाक है। मैंने नहीं किया पता करें आकार (* प्रकार) "अपेक्षित के रूप में" काम करता है – poundifdef

+2

@rascher: वहां कोई 'sizeof (* type)' नहीं है। 'ptr' एक प्रकार नहीं है। यह एक सूचक चर है। – AnT

+1

@rascher: बस स्पष्ट करने के लिए, आप कर सकते हैं या तो 'sizeof (type)' या 'sizeof (अभिव्यक्ति)' का उपयोग करें। बाद के मामले में, कंपाइलर अभिव्यक्ति के प्रकार को कम करता है, लेकिन अभिव्यक्ति स्वयं * मूल्यांकन * नहीं है, इसलिए इसमें मान्य मान नहीं होना चाहिए (उदाहरण के लिए, कोड ऐसा लगता है कि एक शून्य या यूनी dereference लगता है प्रारंभिक सूचक अभी भी ठीक है)। –

4

वे समकक्ष हैं, लेकिन यह लगातार बने रहने के लिए अच्छा है। यह इसे और अधिक स्पष्ट बनाता है, इसलिए यह स्पष्ट है कि आपका क्या मतलब है। यदि प्रकार कभी भी बदलता है, तो यह पता लगाना आसान है कि किस कोड को अपडेट करने की आवश्यकता है।

1

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

4

यह सच हो सकता है, लेकिन यह केवल char के उस विशिष्ट मामले के लिए सच है।

मुझे व्यक्तिगत रूप से लगता है कि malloc(sizeof(char) * 256) फ़ॉर्म का उपयोग करने के लिए यह अच्छा रूप है, क्योंकि कोई व्यक्ति प्रकार बदल रहा है, या एक अलग प्रकार के साथ कोड को कॉपी करने के लिए उस मामले की सूक्ष्मता को याद कर सकता है।

+0

+1 कोड कॉपी करते समय +1। – Cam

+0

'sizeof (char) * 256' आपकी मदद नहीं करता है अगर कोई प्रकार बदलता है; क्या आपका मतलब है' आकार * पीआरटी * 256'? –

+0

@ चार्ल्स, सहमत, उन्हें अभी भी घोषणा में प्रकार बदलना होगा, लेकिन कम से कम यह केवल एक संख्या के बजाय स्पष्ट होगा। –

6

समस्या भी मौजूद नहीं होना चाहिए। आप

ptr = malloc(N * sizeof *ptr) 

के रूप में अपने malloc के लेखन की एक और अधिक सुरुचिपूर्ण मुहावरा अपनाना चाहिए अर्थात जितना संभव हो उतना प्रकार नाम का उल्लेख करने से बचें। टाइप नाम घोषणाओं के लिए हैं, बयान के लिए नहीं।

इस तरह आपका malloc एस हमेशा प्रकार-स्वतंत्र होगा और लगातार दिखाई देगा। तथ्य यह है कि 1 से गुणा गुण अनिवार्य होगा (क्योंकि कुछ लोगों को sizeof(char) परेशानियों से गुणा मिलती है)।

2

sizeof(char) लेखन के साथ तकनीकी रूप से कुछ भी गलत नहीं है, वहीं ऐसा करने का सुझाव है कि लेखक सी और तथ्य यह है कि sizeof(char) के रूप में 1. कुछ परियोजनाओं मैं पर काम किया है में परिभाषित किया गया है से परिचित नहीं है, हम वास्तव में sizeof(char) की घटनाओं के लिए grep एक संकेत के रूप में कि कोड कम गुणवत्ता हो सकता है।

दूसरी ओर, ptr = malloc(count * sizeof(*ptr)); एक बहुत ही उपयोगी प्रलेखन और बग परिहार मुहावरा यह if (count > SIZE_MAX/sizeof(*ptr)) { /* handle overflow */ } से पहले होने की जरूरत है या आप एक गंभीर बग है है, और समझ में आता है, भले ही sizeof(*ptr) 1. हालांकि है। wchar_t या इनपुट स्ट्रिंग के समान लंबाई की जटिल संरचनाओं को आवंटित करते समय यह विशेष रूप से प्रासंगिक हो सकता है, उदाहरण के लिए जब एक यूटीएफ -8 स्ट्रिंग को wchar_t स्ट्रिंग या स्ट्रिंग से मेल खाने के लिए डीएफए बनाते समय कनवर्ट करना।

+0

यह ध्यान देने योग्य है कि यहां तक ​​कि उन प्रणालियों पर जहां एक छोटा 8 बिट्स से बड़ा होता है (मैंने 16 के साथ काम किया है), आकार (char) अभी भी एक है; आकार (int) उस मामले में भी एक है। मैंने उन प्रणालियों के बारे में भी सुना है जहां आकार (लंबा) भी एक है, क्योंकि 'चार' में 64 बिट हैं। – supercat

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