c - सी में सरणी का अधिकतम आकार क्या है?




arrays (5)

एक 64-बिट मशीन सैद्धांतिक रूप से स्मृति के अधिकतम 2 ^ 64 बाइट्स को संबोधित कर सकती है।

मैं समझता हूं कि हार्डवेयर प्रोग्राम निष्पादन के दौरान आवंटित स्मृति की मात्रा को सीमित करेगा। हालांकि, मेरा सवाल हार्डवेयर के संबंध में है। यह मानते हुए कि स्मृति की मात्रा की कोई सीमा नहीं थी, क्या सरणी की कोई सीमा नहीं होगी?


मुझे लगता है कि सबसे बड़ी सैद्धांतिक सरणी "हस्ताक्षरित लंबी" (या जो भी सबसे बड़ा पूर्णांक संख्या नवीनतम मानक / आपका कंपाइलर समर्थन करता है) का अधिकतम मूल्य होगा


सी में सरणी के आकार के लिए कोई निश्चित सीमा नहीं है।

किसी भी ऑब्जेक्ट ऑब्जेक्ट सहित किसी भी ऑब्जेक्ट का आकार SIZE_MAX द्वारा सीमित है, आकार आकार का अधिकतम मान, जो sizeof ऑपरेटर का परिणाम है। (यह पूरी तरह स्पष्ट नहीं है कि सी मानक SIZE_MAX बाइट्स से बड़ी वस्तुओं को अनुमति देता है, लेकिन व्यवहार में ऐसी वस्तुएं समर्थित नहीं हैं; फुटनोट देखें।) चूंकि SIZE_MAX कार्यान्वयन द्वारा निर्धारित किया जाता है, और किसी भी प्रोग्राम द्वारा संशोधित नहीं किया जा सकता है, जो ऊपरी बाउंड लगाता है किसी एकल वस्तु के लिए SIZE_MAX बाइट्स का। (यह ऊपरी बाउंड है, कम से कम ऊपरी सीमा नहीं; कार्यान्वयन हो सकता है, और आम तौर पर, छोटी सीमा लगा सकता है।)

टाइप void* की चौड़ाई, एक सामान्य सूचक प्रकार, निष्पादन प्रोग्राम में सभी ऑब्जेक्ट्स के कुल आकार पर ऊपरी बाध्य लगाता है (जो एक ऑब्जेक्ट के अधिकतम आकार से बड़ा हो सकता है)।

सी मानक इन निश्चित आकारों पर, निम्न सीमाओं को लागू करता है, लेकिन ऊपरी सीमा नहीं। कोई अनुरूप सी कार्यान्वयन अनंत आकार की वस्तुओं का समर्थन कर सकता है, लेकिन यह किसी भी सीमित आकार के सिद्धांतों का समर्थन कर सकता है। व्यक्तिगत सी कार्यान्वयन द्वारा ऊपरी सीमाएं लगाई जाती हैं, जिन वातावरण में वे काम करते हैं, और भौतिकी द्वारा, भाषा द्वारा नहीं।

उदाहरण के लिए, एक अनुरूप कार्यान्वयन हो सकता था SIZE_MAX 2 1024 -1 के बराबर है, जिसका मतलब है कि यह सिद्धांत रूप में कर सकता है 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215 बाइट तक वस्तुओं की है।

अच्छी किस्मत हार्डवेयर खोजने जो वास्तव में ऐसी वस्तुओं का समर्थन करता है।

फुटनोट : कोई स्पष्ट नियम नहीं है कि कोई वस्तु SIZE_MAX बाइट्स से बड़ी नहीं हो सकती है। आप इस तरह के ऑब्जेक्ट पर sizeof ऑपरेटर को उपयोगी रूप से लागू नहीं कर सके, लेकिन किसी अन्य ऑपरेटर की तरह, sizeof ओवरफ्लो हो सकता है; इसका मतलब यह नहीं है कि आप ऐसी वस्तु पर संचालन नहीं कर सके। लेकिन व्यावहारिक रूप से, किसी भी साधु कार्यान्वयन से आकार के किसी भी ऑब्जेक्ट के आकार का प्रतिनिधित्व करने के लिए आकार बड़ा होगा।


सूचक का आकार उस स्मृति को सीमित करेगा जिसे आप एक्सेस कर सकते हैं। यहां तक ​​कि यदि हार्डवेयर असीमित मेमोरी के लिए समर्थन प्रदान करता है, यदि आप सबसे बड़ा डेटाटाइप उपयोग करने में सक्षम हैं, तो 64 बिट है, तो आप केवल 2 ^ 64 बाइट्स मेमोरी तक पहुंच पाएंगे।


सी 99 5.2.4.1 "अनुवाद सीमा" न्यूनतम आकार

कार्यान्वयन कम से कम एक प्रोग्राम का अनुवाद और निष्पादन करने में सक्षम होगा जिसमें निम्नलिखित सीमाओं में से प्रत्येक का कम से कम एक उदाहरण शामिल है: 13)

  • किसी ऑब्जेक्ट में 65535 बाइट्स (केवल होस्ट किए गए वातावरण में)

13) कार्यान्वयन जब भी संभव हो निश्चित अनुवाद सीमा लागू करने से बचना चाहिए।

इससे पता चलता है कि एक अनुरूप कार्यान्वयन किसी ऑब्जेक्ट को संकलित करने से इंकार कर सकता है (जिसमें सरणी शामिल है) short बाइट्स से अधिक के साथ।

PTRDIFF_MAX स्थिर सरणी वस्तुओं के लिए एक व्यावहारिक सीमा प्रतीत होता है

सी 99 मानक 6.5.6 योजक ऑपरेटरों का कहना है:

9 जब दो पॉइंटर्स घटाए जाते हैं, तो दोनों एक ही सरणी ऑब्जेक्ट के तत्वों को इंगित करेंगे, या सरणी ऑब्जेक्ट के अंतिम तत्व से पहले; नतीजा दो सरणी तत्वों की सबस्क्रिप्ट का अंतर है। परिणाम का आकार कार्यान्वयन-परिभाषित है, और इसका प्रकार (एक हस्ताक्षरित पूर्णांक प्रकार) ptrdiff_t है जो <stddef.h> शीर्षलेख में परिभाषित किया गया है। यदि परिणाम उस प्रकार की किसी वस्तु में प्रतिनिधित्व योग्य नहीं है, तो व्यवहार अपरिभाषित है।

जो मेरा तात्पर्य है कि सिद्धांत में ptrdiff_t से बड़े सरणी की अनुमति है, लेकिन फिर आप पोर्टेबल रूप से उनके पते का अंतर नहीं ले सकते हैं।

तो शायद इस कारण से, जीसीसी आपको बस ptrdiff_t तक सीमित कर रहा है। इसका भी उल्लेख है: एक सरणी का अधिकतम आकार "बहुत बड़ा" क्यों है?

मैंने मुख्य रूप से main.c साथ इसका सत्यापन किया है:

#include <stdint.h>

uint8_t a[(X)];

int main(void) {
    return 0;
}

और फिर उबुनबू 17.10 में:

$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ printf '
> #include <stdint.h>
> PTRDIFF_MAX
> SIZE_MAX
> ' | arm-linux-gnueabi-cpp | tail -n2
(2147483647)
(4294967295U)
$ PTRDIFF_MAX == 2147483647 == 2^31 - 1
$
$ # 2lu << 30 == 2^31 == PTRDIFF_MAX + 1
$ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30)' main.c
a.c:5:9: error: size of array ‘a’ is too large
 uint8_t a[(X)];
         ^
$
$ # PTRDIFF_MAX
$ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30) - 1lu' main.c
$

यह भी देखें





arrays