सी संकलित त्रुटि: "चर-आकार की वस्तु को आरंभीकृत नहीं किया जा सकता है"


98

मुझे निम्न कोड के साथ "चर-आकार की वस्तु को आरंभीकृत नहीं किया जा सकता" त्रुटि क्यों मिलती है?

int boardAux[length][length] = {{0}};

जैसा कि डेविड रोड्रिग्ज द्वारा उत्कृष्ट उत्तर में कहा गया है: यदि लंबाई एक चर है, तो आपको याद रखने की आवश्यकता है, लेकिन अगर लंबाई एक संकलन-समय स्थिर है, तो कथन ठीक संकलन करता है।
केसी

ffwd से 2020 -enum {length = 0xF } ; int boardAux[length][length] = {0};
शेफ ग्लेडिएटर

जवाबों:


124

मैं मान रहा हूं कि आप एक C99 कंपाइलर (गतिशील रूप से आकार के सरणियों के लिए समर्थन के साथ) का उपयोग कर रहे हैं। आपके कोड में समस्या यह है कि जिस समय संकलक आपकी परिवर्तनशील घोषणा को देखता है वह यह नहीं जान सकता है कि सरणी में कितने तत्व हैं (मैं यह भी मान रहा हूँ, संकलक त्रुटि से जो lengthसंकलन समय स्थिर नहीं है)।

आपको उस सरणी को मैन्युअल रूप से प्रारंभ करना होगा:

int boardAux[length][length];
memset( boardAux, 0, length*length*sizeof(int) );

मैं इस उद्देश्य के लिए
मॉलॉक का

@helloWorld: स्टैक आवंटित सरणियों के साथ, printf( "%d", boardAux[1][2] )ठीक संकलन करता है। संकलक आकारों को जानता है और जानता है कि स्मृति (1,2) -थ तत्व किस स्थिति में है। यदि आप डायनेमिक एलोकेशन का उपयोग करते हैं, तो सरणी printf("%d", boardAux[ 1*length + 2 ])
यूनि

@AndreyT: memsetकॉल आउट में त्रुटि को इंगित करने के लिए धन्यवाद । मैंने अभी इसे ठीक किया है।
डेविड रॉड्रिग्ज - ड्रिबेन्स

जब मैं lengthहोने के लिए सेट करता हूं तो मुझे C99 कंपाइलर में यह त्रुटि क्यों मिलती है static? C ++ 14 में यह ठीक काम करता है।
मुहम्मद सिसक

26

आपको यह त्रुटि मिलती है क्योंकि C भाषा में आपको वैरिएबल लंबाई सरणियों के साथ इनिशियलाइज़र का उपयोग करने की अनुमति नहीं है। त्रुटि संदेश आपको मूल रूप से मिल रहा है, यह सब कहता है।

6.7.8 प्रारंभिक

...

3 इकाई के प्रकार को आरंभीकृत किया जाना एक अज्ञात आकार या एक वस्तु प्रकार का एक प्रकार होगा जो एक चर लंबाई सरणी प्रकार नहीं है।


आपको यह कहां मिला, क्या आप मुझे लिंक दे सकते हैं?
हेलोवर्ल्ड

1
@helloWorld: यह भाषा मानक (C99) से है। आप एक "कार्य" TC3 साथ प्रति यहां अपडेट हो जाता है प्राप्त कर सकते हैं open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
चींटी

5
ऐसे विषय हैं जिनके लिए कुछ हमेशा आपको अविश्वास करेंगे यदि आप केवल अनौपचारिक स्पष्टीकरण प्रदान करते हैं। चर लंबाई सरणियाँ इन विषयों में से एक हैं। मानक उद्धृत करने के लिए +1।
पास्कल क्यूक

15

यह त्रुटि देता है:

int len;
scanf("%d",&len);
char str[len]="";

यह भी त्रुटि देता है:

int len=5;
char str[len]="";

लेकिन यह ठीक काम करता है:

int len=5;
char str[len]; //so the problem lies with assignment not declaration

आपको निम्नलिखित तरीके से मूल्य डालने की आवश्यकता है:

str[0]='a';
str[1]='b'; //like that; and not like str="ab";

2

सरणी घोषित करने के बाद

int boardAux[length][length];

प्रारंभिक मानों को निर्दिष्ट करने का सबसे सरल तरीका है क्योंकि शून्य लूप के लिए उपयोग कर रहा है, भले ही यह थोड़ा लंबा हो

int i, j;
for (i = 0; i<length; i++)
{
    for (j = 0; j<length; j++)
        boardAux[i][j] = 0;
}

2
memsetसरल और तेज है।
काकाहुइट फ्रिटो

1

इस सवाल का जवाब पहले ही दिया जा चुका है, लेकिन मैं एक और उपाय बताना चाहता हूं जो तेजी से काम करता है और अगर रन-टाइम में लंबाई को बदलना नहीं है तो काम करता है। लंबाई को परिभाषित करने के लिए मुख्य () से पहले मैक्रो #define का उपयोग करें और मुख्य में () आपका इनिशियलाइज़ेशन काम करेगा:

#define length 10

int main()
{
    int boardAux[length][length] = {{0}};
}

मैक्रों को वास्तविक संकलन से पहले चलाया जाता है और लंबाई एक संकलन-समय स्थिर होगी (जैसा कि उनके जवाब में डेविड रोड्रिग्ज ने कहा है)। यह वास्तव में संकलन से पहले 10 के साथ लंबाई स्थानापन्न करेगा।


0

बस लंबाई को एक विपक्ष घोषित करें, अगर ऐसा नहीं है तो आपको गतिशील रूप से मेमोरी आवंटित की जानी चाहिए


2
मुझे लगता है कि आपको यह देखने की जरूरत है कि कॉन्स्ट का मतलब क्या है!
होल्गर

@ होलगर: क्या आपको यकीन है? यदि वह चर जो लंबाई रखता है (सरणी नहीं, बल्कि सरणी लंबाई) एक स्थिर है, तो कंपाइलर सरणी को आरंभीकृत करने के लिए उपयोग करने के लिए लंबाई जानता है। उदाहरण के लिए, "int length = 5; int array [length];" त्रुटि देता है लेकिन " const int length = 5; int array [length];" संकलन ठीक है।
केसी

@ कैसी: लेकिन const int lenght=5; int array[length][length] = {{0}};नहीं होगा।
MestreLion

0
int size=5;
int ar[size ]={O};

/* This  operation gives an error -  
variable sized array may not be 
initialised.  Then just try this. 
*/
int size=5,i;
int ar[size];
for(i=0;i<size;i++)
{
    ar[i]=0;
}

1
ढेर अतिप्रवाह में आपका स्वागत है! कृपया एक अच्छा जवाब लिखने के लिए गाइड पढ़ें: stackoverflow.com/help/how-to-answer आपका वर्तमान उत्तर अस्पष्ट लगता है और इसका कोई स्पष्टीकरण नहीं है
gybandi

-5

C ++ के लिए इस तरह से अलग घोषणा और आरंभीकरण ।।

int a[n][m] ;
a[n][m]= {0};

1
C ++ प्रश्न नहीं
Cacahuete Frito

ऊपर केवल A [n] [m] को इनिशियलाइज़ करता है, न कि पूरे ऐरे को। int [n] [m]; memset (a, 0, (n m sizeof (int)); // सरणी का स्पष्ट मेम अधिकांश कंपाइलर इसकी अनुमति देते हैं: int [n] [m] = {0}; // सभी सदस्यों को 0 से प्रारंभ करें
Chris Reid

-9

तुम यह नहीं कर सकते। सी कंपाइलर स्टैक पर ऐसी जटिल बात नहीं कर सकता है।

आपको ढेर और गतिशील आवंटन का उपयोग करना होगा।

आपको वास्तव में क्या करने की आवश्यकता है:

  • आपके द्वारा आवश्यक मेमोरी का कंप्यूट आकार (n m sizeof (एलिमेंट))
  • मेमोरी आवंटित करने के लिए मॉलॉक (आकार) को कॉल करें
  • एक accessor बनाएँ: int * access (ptr, x, y, rowSize) {return ptr + y * rowSize + x; }

मैट्रिक्स के साथ बातचीत करने के लिए * एक्सेस (बोर्डअक्स, एक्स, वाई, साइज़) = 42 का उपयोग करें।


एक और सवाल, मुझे अनिर्दिष्ट सीमा के साथ सरणी का अमान्य उपयोग क्यों प्राप्त होता है? प्रिंटफ ("% d", बोर्ड [i] [j]);
helloWorld

10
-1 C99 उपयोगकर्ता कोड (इनिशियलाइज़ेशन को छोड़कर) के रूप में स्टैक में गतिशील आवंटन की अनुमति देता है। गतिशील आवंटन करने की आवश्यकता नहीं है।
डेविड रॉड्रिग्ज - 8

@helloWorld क्योंकि सरणी आयामों को जाना जाता है।
पावेल रेड्ज़विलोव्स्की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.