2012-05-20 11 views
6

संभव डुप्लिकेट:
can we give size of static array a variableएक स्थिर सरणी का आकार वैरिएबल क्यों नहीं बनाया जा सकता है?

मैं बच्चे फ़ाइलों के रूप में इस प्रकार से एक में एक सरणी को परिभाषित कर रहा हूँ।

static int arr[siz]; 

यहां siz बाल फ़ाइल के लिए एक वैश्विक चर उपलब्ध है।

<filename>: <line_num> : error : storage size of ‘arr’ isn’t constant 

मैं चर आकार का एक static सरणी क्यों परिभाषित नहीं कर सकते हैं: लेकिन जीसीसी संकलक निम्न त्रुटि पैदा करता है?

संपादित करें: यह केवल static int प्रकार के लिए एक समस्या प्रतीत होता है। यदि मैं से से int के परिवर्तनीय प्रकार को बदलता हूं, तो त्रुटि दूर हो जाती है, भले ही सरणी का आकार एक चर siz पर निर्भर है।

उत्तर

8

चूंकि आपके द्वारा घोषित सरणी का आकार स्थिर नहीं है, आपके पास परिवर्तनीय लंबाई ऐरे (VLA) है। वीएलए मानक द्वारा वीएलए की अनुमति है लेकिन इसके साथ जुड़े कुछ सीमाएं हैं। आपके पास static या extern स्टोरेज क्लास विनिर्देशक के साथ एक चर लंबाई लंबाई सरणी नहीं हो सकती है।

आपके पास static संग्रहण विनिर्देश के साथ एक वीएलए है और इसे C99 मानक द्वारा अनुमति नहीं है।

संदर्भ:

c99 मानक: 6.7.5.2/8

उदाहरण 4 variably फाई एड मोदी की सभी घोषणाओं (VM) प्रकार या तो ब्लॉक गुंजाइश या समारोह प्रोटोटाइप दायरे में रहना होगा। स्थिर या बाहरी स्टोरेज क्लास के साथ घोषित ऐरे ऑब्जेक्ट्स में एक चर लंबाई लंबाई (VLA) प्रकार नहीं हो सकता है। हालांकि, स्थैतिक भंडारण वर्ग विशिष्टता के साथ घोषित एक वस्तु में वीएम प्रकार हो सकता है (यानी, एक वीएलए प्रकार के लिए सूचक)। अंत में, वीएम प्रकार के साथ घोषित सभी पहचानकर्ताओं को सामान्य पहचानकर्ता होना चाहिए और इसलिए, संरचनाओं या संघों के सदस्य नहीं हो सकते हैं।

तो यदि आप static संग्रहण विनिर्देशक के साथ गतिशील आकार सरणी चाहते हैं तो आपको ढेर पर आवंटित गतिशील सरणी का उपयोग करना होगा।

#define MAX_SIZE 256 
static int* gArr; 
gArr = malloc(MAX_SIZE * sizeof(int)); 

संपादित करें:
अपने अपडेट किए गए सवाल का जवाब करने के लिए:
जब आप घोषणा से static कीवर्ड निकालने, वैश्विक को static से घोषित सरणी परिवर्तन का भंडारण विनिर्देशक, ऊपर मानक बोली ध्यान दें, यह स्पष्ट रूप से प्रतिबंध का उल्लेख करता है कि वीएलए को static और extern संग्रहण विनिर्देश के साथ अनुमति नहीं है। जाहिर है, आपको ग्लोबल स्टोरेज विनिर्देश के साथ एक वीएलए रखने की अनुमति है, जो आपके पास static कीवर्ड को हटाने के बाद आपके पास है।

+0

अच्छी तरह से शोध किए गए उत्तर के लिए धन्यवाद। – Abhinav

+0

तो प्रभावी रूप से, यदि मैं जीसीसी-4.3 का उपयोग कर रहा हूं, तो वीएलए को बाहरी और स्थैतिक प्रकार चर के लिए अनुमति नहीं है? यह वही है जो उपयोगकर्ता डीकोडर ने एक और जवाब में एक टिप्पणी में जवाब दिया है। – Abhinav

+0

@ अहिनाव: हाँ, आप सही हैं। 'बाहरी' और 'स्थैतिक' प्रकार भंडारण विनिर्देश के साथ चर के लिए वीएलए की अनुमति नहीं है। आप gcc-4.3 का उपयोग कर रहे हैं जो c99 मानक को comlies। आपके द्वारा संपादित क्वेरी को संबोधित करने के उत्तर का अद्यतन किया गया। –

2

आप संकलन समय पर सरणी आवंटित कर रहे हैं, इसलिए संकलक को सरणी के आकार को पहले से ही जानना है। यदि आप अपने आकार निर्धारित करने की जरूरत है,

#define siz 5 

या

enum ESizes 
{ 
    siz = 5 
}; 

या

const int siz = 5; 

वैकल्पिक: आप एक निरंतर अभिव्यक्ति के रूप में siz घोषित करने के लिए इससे पहले कि आप arr घोषित, उदाहरण के लिए है रन-टाइम, आप इसे malloc का उपयोग करके ढेर पर आवंटित कर सकते हैं:

static int* arr; 
arr = (int*)malloc(siz * sizeof(int)) 

EDIT: जैसा कि एडीडेंटोनियो ने उल्लेख किया है, मेरा उत्तर C89 के लिए मान्य है। सी 99 में इसे परिवर्तनीय आकार के सरणी घोषित करने की अनुमति है।

+0

आपका 'const' उदाहरण गिनता नहीं है। Https://stackoverflow.com/a/18848583 –

1

आप चर आकार के किसी भी सरणी को परिभाषित नहीं कर सकते हैं। ऐसा इसलिए है क्योंकि arr[siz] संकलक (!) आपके सरणी के लिए स्मृति आवंटित करता है (ठीक है, संकलक एक प्रोग्राम बनाता है, जो .., लेकिन विवरण में भटक नहीं है)। हालांकि, रनटाइम (!) पर चर बदल सकते हैं जिसका अर्थ है कि कंपाइलर को यह जानने का कोई मौका नहीं है कि आवंटित करने के लिए कितनी मेमोरी है।

आप क्या कर सकते

static int* arr; 
arr = (int*) calloc(siz,sizeof(int)) 

ये लाइनें एक प्रोग्राम है जो रनटाइम पर स्मृति आवंटित करता है में परिणाम है, इसलिए यह सटीक आकार के साथ-साथ कार्यावधि में परिभाषित किया जा सकता है।

+3

देखें [सी 99 वैरिएबल-लम्बाई Arrays परमिट करता है] (http://stackoverflow.com/questions/7696591/can-we-give-size-of-static-array-a- चर), जब तक वे स्थिर नहीं हैं और बाहरी नहीं हैं। "विविध रूप से संशोधित (वीएम) प्रकारों की सभी घोषणाओं को या तो ब्लॉक स्कोप या फ़ंक्शन प्रोटोटाइप स्कोप पर होना चाहिए। स्थैतिक या बाहरी स्टोरेज-क्लास विनिर्देशक के साथ घोषित ऐरे ऑब्जेक्ट्स में वेरिएबल लम्बाई सरणी (VLA) प्रकार नहीं हो सकता है।" – DCoder

+0

@ डीकोडर मैं जीसीसी 4.3 का उपयोग कर रहा हूं। रचनात्मक टिप्पणी के लिए धन्यवाद। – Abhinav

+4

@ paulsm4, आपका स्वर सिर्फ आक्रामक है, आमतौर पर SO एक दोस्ताना स्थान –

0

आप क्योंकि इसके स्थान (एक गैर-आरंभिकृत चर के मामले में या bss segment) Data Segment में आवंटित किया जाता है चर आकार का एक static सरणी की घोषणा नहीं कर सकते हैं। इसलिए संकलक को संकलन समय पर आकार जानने की आवश्यकता होती है और यदि शिकायत स्थिर नहीं है तो शिकायत होगी।

इसके लिए अंतर्निहित कारण डेटा सेगमेंट आकार उत्पन्न निष्पादन योग्य आकार के आकार में योगदान देता है, जो स्पष्ट रूप से संकलन समय पर बनाया गया है, और इसलिए इसे ठीक किया जाना चाहिए।

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