ये तथाकथित "संरचना हैक" के विभिन्न रूप हैं, comp.lang.c FAQ के प्रश्न 2.6 में चर्चा की गई।
आकार 0 की एक सरणी परिभाषित करना वास्तव में सी में अवैध है, और कम से कम 1 9 8 9 एएनएसआई मानक के बाद से किया गया है। कुछ कंपाइलर्स इसे एक एक्सटेंशन के रूप में अनुमति देते हैं, लेकिन उस पर भरोसा करने से गैर-पोर्टेबल कोड होता है।
इस लागू करने के लिए एक अधिक पोर्टेबल तरह से उदाहरण के लिए, लंबाई 1 की एक सरणी का उपयोग करने के लिए है:
struct foo {
size_t len;
char str[1];
};
आप एक से अधिक sizeof (struct foo)
बाइट्स आवंटित कर सकता है, len
का उपयोग कर आवंटित आकार का ट्रैक रखने के, और फिर सरणी के एनएच तत्व प्राप्त करने के लिए str[N]
तक पहुंचें। चूंकि सी कंपाइलर्स आम तौर पर सरणी सीमाओं की जांच नहीं करते हैं, यह आम तौर पर "काम" करेगा। लेकिन, कड़ाई से बोलते हुए, व्यवहार अपरिभाषित है।
1999 आईएसओ मानक एक विशेषता "लचीला सरणी सदस्यों" कहा जाता है, इस प्रयोग को बदलने के लिए इरादा कहा:
struct foo {
size_t len;
char str[];
};
आप पुराने struct हैक के रूप में एक ही तरीके से इन के साथ सौदा कर सकते हैं, लेकिन व्यवहार है अच्छी तरह से परिभाषित। लेकिन आपको खुद को सभी बहीखाता करना है; sizeof (struct foo)
में अभी भी सरणी का आकार शामिल नहीं है, उदाहरण के लिए।
आप, ज़ाहिर है, एक सूचक के बजाय का उपयोग कर सकते हैं:
struct bar {
size_t len;
char *ptr;
};
और यह एक पूरी तरह से अच्छा दृष्टिकोण है, लेकिन यह अलग अर्थ विज्ञान है। "स्ट्रक्चर हैक" या लचीली सरणी सदस्यों का मुख्य लाभ यह है कि सरणी को बाकी संरचना के साथ आवंटित किया जाता है, और आप memcpy
का उपयोग करके संरचना के साथ सरणी की प्रतिलिपि बना सकते हैं (जब तक लक्ष्य लक्ष्य रहा है ठीक से आवंटित)। एक सूचक के साथ, सरणी को अलग से आवंटित किया जाता है - जो आप चाहते हैं कि हो सकता है या नहीं भी हो सकता है।
कृपया एक उदाहरण प्रदान करें। – Arafangion
structs के बारे में स्पष्टीकरण। C90 में 'LastMemberOfArray [] ',' 99 में' अंतिम MemberOfArray [] 'और गैर-मानक जीएनयू गुओ में 'LastMemberOfArray [0]' तीन मामले हैं। सी 0 9 मामले में, यह एक गंदे हैक अपरिभाषित व्यवहार पर निर्भर है। यदि संरचना के अंत में संरचना पैडिंग बाइट्स हैं तो आपको समस्याएं मिल सकती हैं। सी 99 ने इसे ठीक किया और _flexible array member_ नामक एक प्रकार बनाया, जो एक ही तरीके से काम करता है लेकिन अच्छी तरह से परिभाषित व्यवहार के साथ। और अंत में, गैर मानक जीएनयू एक ही उद्देश्य के लिए शून्य आकार के सरणी की अनुमति देता है। '-std = c99 -pedantic-error' और '[0]' के साथ मानक के रूप में संकलित करें संकलित नहीं होगा। – Lundin
@ लुंडिन का पहला उदाहरण "9 0 में अंतिम मेम्बरऑफएरे [1] 'होना चाहिए था। सरल टाइपो, इसे केवल उन लोगों के लाभ के लिए जोड़ना जो याद नहीं करते हैं। –