অপারেন্ড অ্যারের আকারটি [] "কীভাবে মুছবেন"?


250
Foo* set = new Foo[100];
// ...
delete [] set;

আপনি অ্যারের গণ্ডিটি পাস করেন না delete[]। কিন্তু সেই তথ্য কোথায় জমা আছে? এটি মানসম্মত হয়?


সোর্সফোর্জ.নেট / প্রজেক্টস / প্রফেস মিমি ওপেন সোর্স এবং মেমরি-ম্যানেজারকে প্রতিস্থাপন করে। এখানে আপনি মেমরি পরিচালনা কীভাবে কাজ করে এবং স্মৃতিগুলি বরাদ্দকরণ এবং মোছার জন্য তথ্যগুলি কোথা থেকে আসে তা খুঁজে পেতে পারেন।

1
দ্রষ্টব্য যে ফাস্টএমএম কেবলমাত্র ডেল্ফি / সি ++ বিল্ডার সংকলকগুলির জন্য নির্দিষ্ট, এটি সি ++ এর জন্য কোনও সাধারণ-উদ্দেশ্যে মেমরির পরিচালক নয়। এমনকি এটি সি ++ তেও লেখা হয় না।
রেমি Lebeau

উত্তর:


181

আপনি যখন গাদাতে মেমরি বরাদ্দ করেন, আপনার বরাদ্দকারী আপনি কত স্মৃতি বরাদ্দ করেছেন তা ট্র্যাক করবে keep আপনার বরাদ্দ দেওয়া মেমরির ঠিক আগে এটি সাধারণত "হেড" বিভাগে সংরক্ষণ করা হয়। এইভাবে যখন মেমরিটি মুক্ত করার সময় হয় তখন ডি-বরাদ্দকারী ঠিক কতটা মেমরি মুক্ত করতে পারে তা জানেন।


4
মনে রাখবেন যে এটি কেবল সি ++ এ অ্যারে বরাদ্দগুলিতে প্রযোজ্য। অন্যান্য সমস্ত বরাদ্দ প্রকারের আকারের উপর নির্ভর করে। কিছু লাইব্রেরি সমস্ত বরাদ্দ মাপ সংরক্ষণ করে সাধারণত সাধারণত ডিবাগিং মোডে।
জ্যান লিংস

97
প্রোগ্রামারটির কাছে এই তথ্যগুলি না পাওয়া কেন একেবারে কোনও কারণ নেই। আমি একটি ফাংশনে একটি পয়েন্টারটি পাস করতে এবং এটি মুক্ত করতে পারি, তবে একই ফাংশনে নিজেকে আকার পেতে আমাকে একটি অতিরিক্ত প্যারামিটারের পাশ দিয়ে যেতে হবে। ঐটি কি কোন অনুভূতি সৃষ্টি করবে?
মার্ক রুজন

26
@ মার্ক, এটি একটি সামান্য পরিমাণে অর্থবোধ তৈরি করে, কারণ তত্ত্ব অনুসারে এটি বরাদ্দকারীকে সর্বদা বরাদ্দকৃত ব্লকের আকার (যা অনুরোধকৃত ব্লকের আকারের চেয়ে পৃথক হতে পারে ) সংরক্ষণ করতে মুক্ত করে। নির্দিষ্ট বরাদ্দকারী নকশাগুলি তাদের নিজস্ব উদ্দেশ্যে এই তথ্যটির প্রয়োজন হতে পারে, বা অ-অ্যারে হ্যাপ বরাদ্দের আকার ট্র্যাক করতে টাইপ তথ্য ব্যবহার করতে যথেষ্ট পরিশীলিত হতে পারে না, ইত্যাদি বরাদ্দকারীকে অনুরোধ করা আকার সংরক্ষণ করতে বাধ্য করে (যাতে আপনি না চান অ্যারে আকারটি নিজেই পাস করার দরকার হয়) এটি একটি ছোট্ট ঝাঁকুনি হতে পারে, তবে এটি কল্পনাযোগ্য বরাদ্দকারী ডিজাইনের উপর পারফরম্যান্সের প্রভাব ফেলতে পারে।
ডগ ম্যাকক্লিয়ান

33
দুঃখিত, তবে এই উত্তরটি পয়েন্টটি মিস করে। কোয়ান্টামপিট যা বর্ণনা করেছেন তা হ'ল মেমোরিটি ডিলেক্ট করার জন্য কীভাবে freeজানেন। হ্যাঁ, মেমরি ব্লকের আকারটি "কোথাও" দ্বারা malloc(সাধারণত ব্লকের মধ্যেই) সংরক্ষণ করা হয়, সুতরাং এটি কীভাবে freeজানে। তবে, new[]/ delete[]একটি ভিন্ন গল্প। পরেরটি মূলত malloc/ এর উপরে কাজ করে freenew[]এটি মেমোরি ব্লকে (স্বতন্ত্রভাবে malloc) তৈরি হওয়া উপাদানের সংখ্যাও সংরক্ষণ করে , যাতে পরে delete[]সেই নম্বরটি পুনরুদ্ধার করতে এবং ব্যবহারকারীর সঠিক সংখ্যাকে কল করতে ব্যবহার করতে পারে।
এএনটি

26
অর্থাৎ শারীরিকভাবে দুটি কাউন্টার ব্লকে সংরক্ষণ করা হয়: ব্লকের আকার (বাই malloc) এবং উপাদান গণনা (দ্বারা new[])। দ্রষ্টব্য, পূর্ববর্তীটি পরবর্তীকালের গণনা করতে ব্যবহার করা যাবে না, যেহেতু সাধারণ ক্ষেত্রে মেমরি ব্লকের আকার অনুরোধ করা আকারের অ্যারের জন্য সত্যই প্রয়োজনের চেয়ে বড় হতে পারে। এছাড়াও মনে রাখবেন যে অ্যারে এলিমেন্ট কাউন্টারটি কেবলমাত্র তুচ্ছ নষ্টকারীগুলির সাথে প্রকারের জন্য প্রয়োজন। তুচ্ছ ডেস্ট্রাক্টর সহ ধরণের ক্ষেত্রে কাউন্টারটি সংরক্ষণ করা হয় না new[]এবং অবশ্যই এটি পুনরুদ্ধার করে না delete[]
এন্টি

23

সংকলকগুলির জন্য একটি পদ্ধতির মধ্যে কিছুটা বেশি মেমরি বরাদ্দ করা এবং একটি প্রধান উপাদানটিতে উপাদানগুলির একটি গণনা সংরক্ষণ করা।

এটি কীভাবে করা যেতে পারে তার উদাহরণ:

এখানে

int* i = new int[4];

সংকলক sizeof(int)*5বাইট বরাদ্দ করবে ।

int *temp = malloc(sizeof(int)*5)

প্রথম sizeof(int)বাইটে "4" সংরক্ষণ করবে

*temp = 4;

এবং সেট i

i = temp + 1;

সুতরাং i5 নয়, 4 টি উপাদানের অ্যারে নির্দেশ করবে।

এবং মুছে ফেলা

delete[] i;

নিম্নলিখিত পদ্ধতিতে প্রক্রিয়া করা হবে:

int *temp = i - 1;
int numbers_of_element = *temp; // = 4
... call destructor for numbers_of_element elements
... that are stored in temp + 1, temp + 2, ... temp + 4 if needed
free (temp)

9

তথ্য মানসম্মত নয়। তবে এই তথ্যগুলিতে আমি যে প্ল্যাটফর্মগুলিতে কাজ করেছি সেগুলিতে প্রথম উপাদানটির ঠিক আগে মেমরিতে সঞ্চয় করা হয়। অতএব আপনি তাত্ত্বিকভাবে এটি অ্যাক্সেস করতে এবং এটি পরীক্ষা করতে পারেন, তবে এটির পক্ষে এটি উপযুক্ত নয়।

এছাড়াও এই কারণেই আপনি যখন নতুন [] এর সাথে মেমরি বরাদ্দ করেন তখন অবশ্যই মুছুন [] ব্যবহার করতে হবে, কারণ মোছার অ্যারের সংস্করণটি জানেন যে (এবং কোথায়) সঠিক পরিমাণের মেমরি মুক্ত করতে হবে - এবং যথাযথ সংখ্যক ধ্বংসকারীকে কল করতে হবে বস্তুর জন্য।


5

মূলত এর স্মৃতিতে এটি সাজানো রয়েছে:

[তথ্য] [মেমো আপনি চেয়েছিলেন ...]

তথ্যটি আপনার সংকলক দ্বারা বরাদ্দকৃত মেমরির পরিমাণ সঞ্চয় করার জন্য কী কাঠামো ব্যবহার করা হয় এবং কী নয়।

এটি বাস্তবায়ন নির্ভর যদিও।


4

এটি এমন কিছু নয় যা অনুমেয় - এটি বাস্তবায়ন নির্ভর।


3

এটি সংকলক নির্দিষ্ট হতে সি ++ স্ট্যান্ডার্ডে সংজ্ঞায়িত করা হয়েছে। যার অর্থ কম্পাইলার ম্যাজিক। এটি কমপক্ষে একটি বড় প্ল্যাটফর্মের উপর নন-তুচ্ছ সংশ্লেষের সীমাবদ্ধতাগুলি ভেঙে ফেলতে পারে।

আপনি সম্ভাব্য বাস্তবায়নগুলি অনুধাবন করে ভাবতে পারেন delete[]যা কেবলমাত্র ফিরে আসা পয়েন্টারগুলির জন্যই সংজ্ঞায়িত করা হয়েছে new[], এটি যে পয়েন্টার হিসাবে ফেরানো হয়েছে একই পয়েন্টার নাও হতে পারে operator new[]। ওয়াইল্ডের মধ্যে একটি বাস্তবায়ন হ'ল অ্যারে গণনাটি প্রথম প্রেরণে ফিরে আসে operator new[], এবং new[]সেই পয়েন্টারটি অফসেট দিয়ে ফিরে আসে। (এই কারণেই অ-তুচ্ছ সংশ্লেষগুলি ভেঙে যেতে পারে new[]))

মনে রাখবেন যে operator new[]/operator delete[]! = new[]/delete[]

এছাড়াও, সি কীভাবে বরাদ্দকৃত মেমরির আকার জানবে তার পক্ষে এটি অরথোগোনাল malloc


2

কারণ 'মুছুন' এমন অ্যারে 'নতুন' অপারেটরের একক ব্যবহারের সাথে তৈরি করা উচিত ছিল। 'নতুন' ক্রিয়াকলাপটি সেই তথ্যটি হ'ল রাখা উচিত ছিল। অন্যথায়, অতিরিক্ত অতিরিক্ত ব্যবহারগুলি কীভাবে জানবে যে গাদা কোথায় শেষ?


0

এটি মানসম্মত নয়। মাইক্রোসফ্টের রানটাইমে নতুন অপারেটর ম্যালোক () এবং ডিলিট অপারেটর বিনামূল্যে () ব্যবহার করে। সুতরাং, এই সেটিংয়ে আপনার প্রশ্ন নীচের সমতুল্য: ফ্রি () কীভাবে ব্লকের আকার জানতে পারে?

পর্দার আড়ালে কিছু বুককিপিং চলছে, অর্থাত সি রানটাইমে।


5
সত্য না. বিনামূল্যে কল করার আগে, মুছে ফেলার জন্য [] প্রথমে ধ্বংসকারীদের কল করতে হবে। এটি জানার জন্য মোট বরাদ্দের পরিমাণ যথেষ্ট নয়। প্রকৃতপক্ষে নতুন [] এবং মুছুন [] উপাচার্য ++ এ প্লেইন এবং ধ্বংসাত্মক ধরণের জন্য আলাদাভাবে কাজ করে।
সুমা

0

এটি প্রথমে আপনি যা ভাবেন তার চেয়েও আকর্ষণীয় সমস্যা। এই উত্তরটি একটি সম্ভাব্য বাস্তবায়ন সম্পর্কে।

প্রথমত, আপনার সিস্টেমে কোনও স্তরে মেমরি ব্লককে কীভাবে 'ফ্রি' করতে হয় তা জানতে হবে, অন্তর্নিহিত ম্যালোক / ফ্রি (যা নতুন / মোছা / নতুন [] / মোছা [] সাধারণত কল করে) ঠিক কতটা মেমরি স্মরণ করে না আপনার কাছে জিজ্ঞাসা করুন, এটি বৃত্তাকার হয়ে উঠতে পারে (উদাহরণস্বরূপ, একবার আপনি 4K এর উপরে গেলে এটি প্রায়শই পরবর্তী 4K-আকারের ব্লক পর্যন্ত গোল হয়ে যায়)।

সুতরাং, এমনকি যদি মেমরি ব্লকের আকার পেতে পারে তবে এটি নতুন [] এড মেমরিতে কতগুলি মান রয়েছে তা আমাদের জানায় না, এটি আরও ছোট হতে পারে। অতএব, আমাদের আরও একটি পূর্ণসংখ্যা সঞ্চয় করতে হবে যা আমাদের জানায় যে সেখানে কতগুলি মান রয়েছে।

ব্যতীত, যদি নির্মাণ করা ধরণের কোনও ডেস্ট্রাক্টর না থাকে তবে মুছে ফেলা [] মেমরি ব্লক ব্যতীত আর কিছুই করতে হবে না, এবং তাই কোনও কিছু সঞ্চয় করতে হবে না!

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