সি সংকলন ত্রুটি: "পরিবর্তনশীল-আকারের অবজেক্টটি আরম্ভ করা যাবে না"


99

নিম্নলিখিত কোড সহ আমি কেন "পরিবর্তনশীল-আকারের অবজেক্টটি আরম্ভ করা যেতে পারে না" ত্রুটিটি পাব?

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

ডেভিড রদ্রিগেজের চমৎকার উত্তরে যেমন উল্লেখ করা হয়েছে: দৈর্ঘ্য যদি একটি পরিবর্তনশীল হয় তবে আপনার স্মৃতিচিহ্নের প্রয়োজন হয় তবে দৈর্ঘ্য যদি একটি সংকলন-সময় ধ্রুবক হয় তবে বিবৃতিটি ঠিক জরিমানা করে।
কেসি

এফএফডাব্লুড 2020 -enum {length = 0xF } ; int boardAux[length][length] = {0};
শেফ গ্ল্যাডিয়েটার

উত্তর:


126

আমি ধরে নিচ্ছি যে আপনি C99 সংকলক ব্যবহার করছেন (গতিশীল আকারের অ্যারেগুলির জন্য সমর্থন সহ)। আপনার কোডের সমস্যাটি হ'ল সেই সময়টি যখন সংকলকরা আপনার পরিবর্তনশীল ঘোষণাটি দেখতে পায় তখন এটি জানতে পারে না যে অ্যারেতে রয়েছে কতগুলি উপাদান (আমি এখানেও ধরে নিচ্ছি, সংকলক ত্রুটি যা lengthসংকলনের সময় ধ্রুবক নয়)।

আপনাকে অবশ্যই ম্যানুয়ালি সেই অ্যারেটি শুরু করতে হবে:

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

আমি এই উদ্দেশ্যটির জন্যও ব্যবহার করতে পারি, দ্বিতীয় প্রশ্নটি কী, আমি পাভেলের জবাবের পরে এটি লিখেছিলাম
হ্যালো ওয়ার্ল্ড

@ হেলো ওয়ার্ল্ড: স্ট্যাক বরাদ্দ অ্যারে সহ, printf( "%d", boardAux[1][2] )সূক্ষ্ম সংকলন করে। সংকলক আকারগুলি জানে এবং মেমোরিতে (1,2) তম উপাদানটি কী অবস্থানে তা জানে। আপনি যদি গতিশীল বরাদ্দ ব্যবহার করেন তবে অ্যারেটি দ্বিমাত্রিক এবং আপনাকে নিজেই গণিতটি সম্পাদন করতে হবে:printf("%d", boardAux[ 1*length + 2 ])
ডেভিড রডগ্রিজেজ - ড্রিবিয়াস

@ অ্যান্ড্রেটি: memsetকল আউটে ত্রুটিটি নির্দেশ করার জন্য ধন্যবাদ । আমি ঠিক এটি সংশোধন করেছি।
ডেভিড রদ্রিগেজ - ড্রিবিস

যখন আমি সেট কেন আমি C99 কম্পাইলার এই ত্রুটির পেতে পারি lengthহতে static? সি ++ 14 এ এটি সূক্ষ্মভাবে কাজ করে।
সিলিড্রোন

কেন mallocপ্রয়োজন হয় না তা জানতে চাই ।
মজেন্ড

26

আপনি এই ত্রুটিটি পান কারণ সি ভাষায় আপনাকে পরিবর্তনশীল দৈর্ঘ্যের অ্যারে সহ প্রারম্ভিক ব্যবহার করার অনুমতি নেই। আপনি যে ত্রুটি বার্তাটি পাচ্ছেন তা মূলত এটি সব বলে।

6.7.8 সূচনা

...

3 প্রারম্ভিক হওয়ার জন্য সত্তার প্রকারটি অজানা আকারের একটি অ্যারে বা কোনও বস্তুর প্রকার যা কোনও চলক দৈর্ঘ্যের অ্যারে প্রকার নয়।


আপনি এটি কোথায় পেয়েছেন, আপনি আমাকে একটি লিঙ্ক দিতে পারেন?
হ্যালো ওয়ার্ল্ড

4
@ হেলো ওয়ার্ল্ড: এটি ভাষা মান (সি 99) থেকে এসেছে। আপনি এখানে টিসি 3 আপডেটের সাথে "ওয়ার্কিং" অনুলিপিটি পেতে পারেন ওপেন-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
এএনটি

4
এমন কিছু বিষয় রয়েছে যার জন্য কিছু আপনি সর্বদা আপনাকে অস্বীকার করবেন যদি আপনি কেবল অনানুষ্ঠানিক ব্যাখ্যা সরবরাহ করেন। চলক দৈর্ঘ্যের অ্যারে এই বিষয়গুলির মধ্যে একটি। মানটি উদ্ধৃত করার জন্য +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";

3

অ্যারে ঘোষণা করার পরে

int boardAux[length][length];

শূন্য হিসাবে প্রাথমিক মানগুলি নির্ধারণের সহজ উপায়টি লুপের জন্য ব্যবহার করা হয়, যদিও এটি কিছুটা দীর্ঘও হতে পারে

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

4
memsetসহজ এবং দ্রুত।
কাকাহুতে ফ্রেটো

3

প্রশ্নের ইতিমধ্যে উত্তর দেওয়া হয়েছে তবে আমি অন্য একটি সমাধানটি নির্দেশ করতে চাই যা দ্রুত এবং এটি কাজ করে যদি দৈর্ঘ্যটি রান-টাইমে পরিবর্তন করা না হয়। দৈর্ঘ্য নির্ধারণ করতে প্রধান () এর পূর্বে ম্যাক্রো # ডেফাইন ব্যবহার করুন এবং প্রধান () আপনার প্রাথমিককরণটি কাজ করবে:

#define length 10

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

প্রকৃত সংকলনের আগে ম্যাক্রোগুলি চালিত হয় এবং দৈর্ঘ্যটি একটি সংকলন-সময় ধ্রুবক হবে (যেমনটি তার উত্তরে ডেভিড রদ্রেগেজ উল্লেখ করেছেন)। সংকলনের আগে এটি 10 ​​এর দৈর্ঘ্যের পরিবর্তিত হবে।


1

অ্যারেটি মেমরির দ্বারা নির্দিষ্ট করা এফটি একটি ত্রুটি নিক্ষেপ করে আরম্ভ করা হয় না variable sized array may not be initialised আমি প্রথমে প্রাথমিককরণ পছন্দ করি,

for (i = 0; i <= bins; i++)
        arr[i] = 0;

0

কেবল দৈর্ঘ্যকে কনস হিসাবে ঘোষনা করুন, যদি তা না হয় তবে আপনার গতিশীলভাবে মেমরি বরাদ্দ করা উচিত


4
আমি মনে করি আপনার কনস্টের মানে কী তা খতিয়ে দেখার দরকার!
হলগার

@ হালগার: আপনি কি নিশ্চিত? যদি দৈর্ঘ্যটি ধারণ করে এমন পরিবর্তনশীল (অ্যারে নিজেই নয়, তবে অ্যারের দৈর্ঘ্য) একটি ধ্রুবক হয়, তবে সংকলক অ্যারে শুরু করার জন্য ব্যবহার করতে দৈর্ঘ্যটি জানেন। উদাহরণস্বরূপ, "int দৈর্ঘ্য = 5; ইন্ট অ্যারে [দৈর্ঘ্য];" ত্রুটিটি দেয় তবে " কনস্ট ইনট দৈর্ঘ্য = 5; ইনট অ্যারে [দৈর্ঘ্য]"; ঠিক জরিমানা সংকলন।
ক্যাসি

@ ক্যাসি: তবে তা 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;
}

4
স্ট্যাক ওভারফ্লোতে স্বাগতম! : দয়া করে কিভাবে ভাল উত্তর লিখতে উপর নির্দেশ পড়ুন stackoverflow.com/help/how-to-answer আপনার বর্তমান উত্তর অস্পষ্ট মনে হয় এবং এটি কোনো ব্যাখ্যা নেই
gybandi

-5

সি ++ এর মতো পৃথক ঘোষণা এবং প্রারম্ভিককরণের জন্য ..

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

4
কোনও সি ++ প্রশ্ন নয়
কাকাহুয়েত ফ্রিটো

উপরের অংশটি কেবলমাত্র [এন] [এম] শুরু করে, পুরো অ্যারেটি নয়। int a [n] [মি]; মেমসেট (ক, ০, (এন এম আকারে (ইনট্রি)); // অ্যারের স্পষ্ট স্মৃতি মেমরির সংকলক বেশিরভাগ সংকলক এটিকে মঞ্জুরি দেয়: int a [n] [m] = {0}; // সকল সদস্যকে 0-এ শুরু করুন
ক্রিস রেড

-9

তুমি এটা করতে পারবেনা. সি সংকলক স্ট্যাকের উপর এ জাতীয় জটিল জিনিস করতে পারে না।

আপনাকে গাদা এবং গতিশীল বরাদ্দ ব্যবহার করতে হবে।

আপনার সত্যিই যা করা দরকার:

  • আপনার প্রয়োজনীয় মেমরির গণনা আকার (এন মিটার আকার ( উপাদান))
  • মেমরি বরাদ্দ করতে কল malloc (আকার)
  • একটি অ্যাক্সেসর তৈরি করুন: int * অ্যাক্সেস (পিটিআর, এক্স, ওয়াই, সারি সাইজ) {পিটিআর + ওয়াই * সারি সাইজ + এক্স; }

ম্যাট্রিক্সের সাথে ইন্টারঅ্যাক্ট করতে * অ্যাক্সেস (বোর্ডআক্স, এক্স, ওয়াই, আকার) = 42 ব্যবহার করুন।


আরও একটি প্রশ্ন, আমি কেন অনির্দিষ্ট সীমানা সহ একটি ত্রুটিযুক্ত অ্যারের ব্যবহার গ্রহণ করব? প্রিন্টফ ("% ডি", বোর্ড [i] [জে]);
হ্যালো ওয়ার্ল্ড

10
-1 সি 99 স্ট্যাকের গতিশীল বরাদ্দকে ব্যবহারকারীর কোড হিসাবে (আরম্ভিকরণ বাদে) অনুমতি দেয়। গতিশীল বরাদ্দ সম্পাদন করার প্রয়োজন নেই।
ডেভিড রদ্রিগেজ - ড্রিবিস

@ হেলো ওয়ার্ল্ড কারণ অ্যারে মাত্রা জানা উচিত।
পাভেল রদজিভিলভস্কি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.