সি ++ নতুন ইনট [0] - এটি কি স্মৃতি বরাদ্দ করবে?


241

একটি সাধারণ পরীক্ষা অ্যাপ্লিকেশন:

cout << new int[0] << endl;

আউটপুট:

0x876c0b8

সুতরাং দেখে মনে হচ্ছে এটি কাজ করে। স্ট্যান্ডার্ড এ সম্পর্কে কী বলে? মেমরির খালি ব্লকটি "বরাদ্দ" করা কি সর্বদা আইনী?


4
+1 খুব আকর্ষণীয় প্রশ্ন - যদিও আমি নিশ্চিত নই যে এটি বাস্তব কোডে কতটা গুরুত্বপূর্ণ।
জিফ্রে

37
@ জিফ্রে: আমি কৌতূহল চাইছি, তবে এটি বাস্তব বিশ্বে গুরুত্বপূর্ণ হতে পারে, যেমন বরাদ্দকৃত মেমরি ব্লকের আকারটি কোনও উপায়ে গণনা করা হয় এবং গণনার ফলাফল শূন্য হতে পারে, তখন ব্যতিক্রম যুক্ত করার সরাসরি কোনও প্রয়োজন নেই শূন্য আকারের ব্লকগুলি বরাদ্দ না করার জন্য .. কারণ এগুলিকে বরাদ্দ করতে হবে এবং ত্রুটি ছাড়াই মুছে ফেলা উচিত (কেবলমাত্র শূন্য আকারের ব্লকটি যদি অবধারিত না হয়)। সুতরাং সাধারণত এটি মেমরির ব্লক কী তার বিস্তৃত বিস্তৃতি দেয়।

2
@ ইমগ -২: আপনার উদাহরণস্বরূপ পরিস্থিতিতে, এটি আসলে কিছু যায় আসে না, কারণ মোছা [] একটি নল পয়েন্টার :-) এ পুরোপুরি আইনী।
ইভান তেরান

2
এটি কেবলমাত্র তাত্পর্যপূর্ণভাবে সম্পর্কিত - তাই আমি এখানে মন্তব্য করছি - তবে সি ++ বিভিন্ন উপায়ে নিশ্চিত করে যে স্বতন্ত্র বস্তুর স্বতন্ত্র ঠিকানা রয়েছে ... এমনকি যদি তাদের স্পষ্টত স্টোরেজ প্রয়োজন না হয়। একটি সম্পর্কিত পরীক্ষাটি খালি কাঠামোর আকার চেক করা হবে। বা স্ট্রাক্টের একটি অ্যারে।
ড্রু ডোরম্যান

2
শ্মোপটির মন্তব্যটি বিশদভাবে জানাতে: বিশেষত যখন টেমপ্লেটগুলি (যেমন নীতিগত শ্রেণীর টেমপ্লেটগুলি যেমন স্ট্যান্ড :: বরাদ্দকারী) এর সাথে প্রোগ্রামিং করা হয় তখন সি ++ এ শূন্য-আকারের অবজেক্ট থাকা সাধারণ common জেনেরিক কোডকে এ জাতীয় অবজেক্টগুলি গতিশীলভাবে বরাদ্দ করতে হবে এবং অবজেক্টের পরিচয় তুলনা করতে তাদের পয়েন্টার ব্যবহার করতে হবে। এজন্য অপারেটর নতুন () শূন্য-আকারের অনুরোধগুলির জন্য অনন্য পয়েন্টারগুলি প্রদান করে। তর্কযোগ্যভাবে কম গুরুত্বপূর্ণ / সাধারণ হলেও একই যুক্তি অ্যারে বরাদ্দ এবং অপারেটর নতুন [] () এর ক্ষেত্রে প্রযোজ্য।
ট্রেভর রবিনসন

উত্তর:


233

5.3.4 / 7 থেকে

যখন সরাসরি-নতুন-ঘোষকটিতে অভিব্যক্তির মান শূন্য হয়, বরাদ্দ ফাংশনটি কোনও উপাদান ছাড়াই একটি অ্যারে বরাদ্দ করতে বলা হয়।

৩. 3..৩.১/২০১। থেকে

শূন্য আকারের জন্য একটি অনুরোধ হিসাবে ফিরে আসা পয়েন্টারের ডিফারেন্সিংয়ের প্রভাব অপরিজ্ঞাত।

এছাড়াও

অনুরোধ করা জায়গার আকার [নতুন দ্বারা] শূন্য হলেও, অনুরোধটি ব্যর্থ হতে পারে।

তার মানে আপনি এটি করতে পারেন, তবে আপনি আইনীভাবে (সমস্ত প্ল্যাটফর্ম জুড়ে একটি সুস্পষ্ট সংজ্ঞায়িত পদ্ধতিতে) আপনার যে স্মৃতি পেয়েছেন তা হ্রাস করতে পারবেন না - আপনি কেবল এটি অ্যারে মুছতে পাস করতে পারেন - এবং আপনার এটি মুছে ফেলা উচিত।

এখানে একটি আকর্ষণীয় পাদটীকা রয়েছে (উদাহরণস্বরূপ মানের কোনও আদর্শিক অংশ নয়, তবে এক্সপোজারিটরি উদ্দেশ্যে অন্তর্ভুক্ত) বাক্যটির সাথে সংযুক্ত 3.7.3.1/2

[32। অভিপ্রায়টি হ'ল malloc () বা কলোক () কল করে অপারেটর নতুন () প্রয়োগযোগ্য হবে, সুতরাং নিয়মগুলি যথেষ্ট পরিমাণে একই stan নন-নাল পয়েন্টারটি ফেরত দেওয়ার জন্য শূন্যের অনুরোধের ক্ষেত্রে সি ++ সি থেকে আলাদা হয় fers]


আমি মুছে না ফেললে আমি একটি মেমরি ফাঁস করি। এটা আশা করা হয়? কমপক্ষে আমি আশা করিনি।
এরালপবি

12
@ ইরালপবি: বিপরীতে, আপনার অনুরোধ শূন্য হলেও এই বরাদ্দাগুলি হিপগুলিতে ঘটে, যেখানে একটি অনুরোধে বুক রক্ষার বিভিন্ন কার্যক্রম বোঝানো হয়, যেমন বরাদ্দকারীর প্রদত্ত জোনটির আগে এবং পরে হিল গার্ডদের বরাদ্দকরণ এবং আরম্ভ করার মতো, ফ্রিলিস্টগুলিতে সন্নিবেশ বা অন্যান্য জটিল ভয়ঙ্কর কাঠামো। এটি মুক্ত করার অর্থ পশ্চাদপদ হিসাবরক্ষণ করা।
v.oddou

3
@ ইরালপবি হ্যাঁ আমার ধারণা আপনি যতবারই মাপের new[]সাথে ভারসাম্য রাখবেন না delete[]- আপনি মেমরি ফাঁস আশা করতে পারেন the বিশেষত, যখন আপনি কল করবেন তখন new[i]অ্যারের আকার সংরক্ষণ করার জন্য যা delete[]বরাদ্দ করার চেষ্টা করছেন তার চেয়ে কিছুটা বেশি মেমোরি প্রয়োজন (যা পরে পরে নির্ধারণের পরে ব্যবহৃত হয় )
pqnet

24

হ্যাঁ, এটির মতো শূন্য আকারের অ্যারে বরাদ্দ করা বৈধ। তবে আপনাকে অবশ্যই এটি মুছে ফেলতে হবে।


1
আপনি কি এই জন্য একটি প্রশংসাপত্র আছে? আমরা সবাই জানি যে int ar[0];বেআইনী কেন নতুন ঠিক আছে?
মোটি

4
এটি আকর্ষণীয় যে সি ++ শূন্য আকারের অবজেক্টগুলিকে নিষিদ্ধ করার সাথে এতটা শক্তিশালী নয়। খালি বেস শ্রেণীর অপ্টিমাইজেশানটির কথা ভাবেন: এখানেও খালি বেস শ্রেণির সাব-অবজেক্টটির আকার শূন্য হতে পারে। বিপরীতে, সি স্ট্যান্ডার্ড জিরো আকারের বস্তুগুলি কখনই তৈরি হয় না তা নিশ্চিত করার জন্য একটি দৃ effort় প্রচেষ্টা করে: ম্যালোক (0) সংজ্ঞায়িত করার ক্ষেত্রে এটি বলে যে প্রভাবটি কিছু শূন্য-যুক্তির সাহায্যে মলোক চলমান, উদাহরণস্বরূপ। এবং কাঠামোয় {...; টি এন []; }; অ্যারে (এফএএম) এর জন্য যখন কোনও স্থান বরাদ্দ নেই, তখন এটি বলে যে এটি এমন আচরণ করে যে "এন" এর একটি উপাদান রয়েছে। (উভয় ক্ষেত্রেই, অবজেক্টটিকে যে কোনও উপায়ে ব্যবহার করা
হ'ল ইউএন, এক্সএন-এর

1
আমি মনে করি sizeof (type)কখনই শূন্যের প্রত্যাবর্তন হবে না। : যেমন দেখুন stackoverflow.com/questions/2632021/can-sizeof-return-0-zero
pqnet

এমনকি তথাকথিত "খালি বেস শ্রেণীর অপ্টিমাইজেশন" কেবলমাত্র একটি দৃ an়তার কারণে প্রাসঙ্গিক যে সমস্ত বস্তুর (বস্তুর মধ্যে থাকা সমস্ত বাইটের বিপরীতে) অনন্য ঠিকানা থাকতে হবে। সি ++ আরও সহজ করা যেতে পারত যদি অনন্য অ্যাড্রেসযুক্ত বস্তুগুলির বিষয়ে প্রকৃত পরিচর্যা করা কোডটি তাদের শূন্য-আকারের না তা নিশ্চিত করার জন্য প্রয়োজন হত।
সুপারক্যাট

15

স্ট্যান্ডার্ড এ সম্পর্কে কী বলে? মেমরির খালি ব্লকটি "বরাদ্দ" করা কি সর্বদা আইনী?

প্রতিটি বস্তুর একটি স্বতন্ত্র পরিচয়, অর্থাত্ একটি অনন্য ঠিকানা, যা একটি শূন্য-দৈর্ঘ্য বোঝায় (মেমরির আসল পরিমাণটি নিঃশব্দে বৃদ্ধি পাবে, যদি আপনি শূন্য বাইট চেয়ে থাকেন)।

আপনি যদি এইগুলির একটিরও বেশি বরাদ্দ করেন তবে আপনি দেখতে পাবেন যে তাদের আলাদা ঠিকানা রয়েছে।


"প্রতিটি বস্তুর একটি স্বতন্ত্র পরিচয়, অর্থাত্ একটি অনন্য ঠিকানা, যা একটি শূন্য-দৈর্ঘ্য বোঝায়" - সত্য, তবে ভুল। অবজেক্টের ঠিকানা রয়েছে তবে অবজেক্টের পয়েন্টারটি এলোমেলো স্মৃতিতে নির্দেশ করতে পারে। "আপনি যদি শূন্য বাইট চেয়ে থাকেন তবে মেমরির আসল পরিমাণটি নিঃশব্দে বাড়বে" - নিশ্চিত নন। operator []এছাড়াও অ্যারের আকারটি কোথাও সঞ্চয় করে ( isocpp.org/wiki/faq/freestore-mgmt#num-elems-in-new-array দেখুন )। সুতরাং যদি প্রয়োগটি ডেটা সহ বাইট গণনা বরাদ্দ করে তবে এটি কেবল বাইট গণনা এবং ডেটার জন্য 0 বাইটের জন্য বরাদ্দ করতে পারে, 1-গত-শেষ পয়েন্টারটি ফিরিয়ে দেয়।
স্টিড

বরাদ্দ মেমরির একটি শূন্য-দৈর্ঘ্য, ব্যবহারযোগ্য মেমরির একটি শূন্য-দৈর্ঘ্য নয়। আমার বক্তব্যটি ছিল দুটি স্বতন্ত্র বস্তুর প্রতি দুটি পয়েন্টার একই ঠিকানার দিকে নির্দেশ করা উচিত নয়।
ChrisW

1
স্ট্যান্ডার্ড ( ওপেন-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf ) সত্যিই বলেছে (3.7.4.1/2) যে বিভিন্ন কলকে operator new[]বিভিন্ন পয়েন্টার ফিরে আসা উচিত। new expressionবিটিডাব্লু , এর কিছু অতিরিক্ত নিয়ম রয়েছে (৫.৩.৪) new0 আকারের সাথে আসলে কিছু বরাদ্দ করা দরকার এমন কোনও ক্লু আমি খুঁজে পাইনি। দুঃখিত, আমি হ্রাস পেয়েছি কারণ আমি দেখতে পেয়েছি যে আপনার উত্তর প্রশ্নের উত্তর দিচ্ছে না, তবে কিছু বিতর্কিত বক্তব্য সরবরাহ করছে।
স্টিড

@ স্ট্রিড মেমরিটি ব্লকের দৈর্ঘ্য সংরক্ষণ করার জন্য ঠিকানা স্পেস ব্যবহার করে সুস্পষ্টভাবে গণনা করা যেতে পারে। উদাহরণস্বরূপ শূন্য আকারের অ্যারেগুলির জন্য new[]বাস্তবায়নের পক্ষে এমন কোনও পরিসরে ঠিকানাগুলি
ফেরানো

@ পিকিউনেট: একটি ভাল মানের প্রয়োগের জন্য সীমাহীন সংখ্যক নতুন / মোছার চক্রের অনুমতি দেওয়া উচিত, তাই না? -৪-বিট পয়েন্টার সহ একটি প্ল্যাটফর্মে এটি যুক্তিযুক্ত হতে পারে যে কোনও কম্পিউটার পুনরায় ব্যবহারের while(!exitRequested) { char *p = new char[0]; delete [] p; }ছাড়াই একটি লুপ চালাচ্ছে এটি সম্ভবত ঠিকানা স্থানের বাইরে চলে যাওয়ার আগে ধূলিতে পড়ে যাবে, তবে ৩২-বিট পয়েন্টারযুক্ত প্ল্যাটফর্মে যেটি হবে অনেক কম যুক্তিসঙ্গত অনুমান।
সুপারক্যাট

14

হ্যাঁ এটি 0দিয়ে একটি আকারের ব্লক বরাদ্দ করা সম্পূর্ণ আইনী new। আপনার অ্যাক্সেসের জন্য কোনও বৈধ ডেটা নেই বলে আপনি কেবল এটির সাথে দরকারী কিছু করতে পারবেন না। int[0] = 5;অবৈধ।

তবে, আমি বিশ্বাস করি যে স্ট্যান্ডার্ডটি জিনিসগুলিতে malloc(0)ফিরে আসতে পছন্দ করে NULL

delete []বরাদ্দ থেকে আপনি যে কোনও পয়েন্টার ফিরে পেতে পারেন তার জন্য আপনার এখনও প্রয়োজন হবে ।


5
ম্যালোক সম্পর্কিত, আপনি সঠিক - এটি বাস্তবায়ন সংজ্ঞায়িত হয়। এটি প্রায়শই একটি ভুল ধারণা হিসাবে দেখা হয়।

আমি মনে করি একটি আকর্ষণীয় প্রশ্ন হ'ল: 0 এর আকার দেওয়া হলে নতুন রিটার্নের নটর সংস্করণটি NULL করতে পারে?
ইভান তেরান

1
নতুন এবং ম্যালোকের শব্দার্থবিজ্ঞান কোনওভাবেই লিঙ্কযুক্ত নয়, কমপক্ষে মানক দ্বারা।

তারা হচ্ছে না বলে ... বিশেষত নতুনের নোহর সংস্করণ সম্পর্কে জিজ্ঞাসা করছিলেন।
ইভান তেরান

@ ইভান - কেবলমাত্র অনুরোধটি ব্যর্থ হলেই কেবল নতুন রিটার্নের নোহর সংস্করণ বাতিল হয় - কেবলমাত্র অনুরোধের আকার 0 @ নীল নয় - সাধারণভাবে সংযুক্ত নয় - তবে অভিযুক্তির সাথে সংযুক্ত (যেমন অপারেটর নতুন মলোকের ক্ষেত্রে প্রয়োগ করা যেতে পারে তবে অন্যটি নয়) উপায় প্রায়) - আমি আমার উত্তরে অন্তর্ভুক্ত পাদটীকা দেখুন
ফয়সাল ভালি

1

কৌতূহলজনকভাবে, সি ++ এর জন্য অপারেটরের নতুনকে বৈধ পয়েন্টার প্রদানের প্রয়োজন হয় এমনকি শূন্য বাইটের জন্য অনুরোধ করা হলেও। (এই অদ্ভুত-স্বাদযুক্ত আচরণের প্রয়োজনের ফলে ভাষার অন্য কোথাও জিনিস সহজতর হয়))

আমি কার্যকর সি ++ তৃতীয় সংস্করণটি "আইটেম 51: নতুন লেখার সময় কনভেনশন মেনে চলুন এবং মুছুন" তে এটি বলেছি found


0

আমি আপনাকে গ্যারান্টি দিচ্ছি যে নতুন ইনট [0] আপনার অতিরিক্ত জায়গার জন্য ব্যয় করেছে যেহেতু আমি এটি পরীক্ষা করেছি।

উদাহরণস্বরূপ, এর মেমরি ব্যবহার

int **arr = new int*[1000000000];

তুলনায় উল্লেখযোগ্যভাবে ছোট

int **arr = new int*[1000000000];
for(int i =0; i < 1000000000; i++) {
    arr[i]=new int[0];
}

প্রথম কোড স্নিপেটের দ্বিতীয় কোড স্নিপেট বিয়োগের মেমরির ব্যবহার হ'ল অসংখ্য নতুন ইনট [0] এর জন্য ব্যবহৃত মেমরি।

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