সি ++ এ আবর্জনার কী হবে?


51

জাভাতে একটি স্বয়ংক্রিয় জিসি রয়েছে যা একবারে দ্য ওয়ার্ল্ডকে থামিয়ে দেয় তবে স্তূপে আবর্জনার যত্ন নেয়। এখন সি / সি ++ অ্যাপ্লিকেশনগুলির এই এসটিডাব্লু হিমায়িত হয় না, তাদের মেমরির ব্যবহারও সীমিতভাবে বৃদ্ধি পায় না। এই আচরণ কীভাবে অর্জিত হয়? কিভাবে মৃত জিনিস যত্ন নেওয়া হয়?


38
দ্রষ্টব্য: স্টপ-দ্য ওয়ার্ল্ড হ'ল কিছু আবর্জনা সংগ্রহকারীদের বাস্তবায়ন পছন্দ, তবে অবশ্যই সমস্ত নয়। উদাহরণস্বরূপ, একযোগে জিসি রয়েছে যা মিউটরের সাথে একযোগে চলমান (এটিই জিসি বিকাশকারীরা প্রকৃত প্রোগ্রামকে কল করে)। আমি বিশ্বাস করি আপনি আইবিএমের ওপেন সোর্স জেভিএম জে 9 এর একটি বাণিজ্যিক সংস্করণ কিনতে পারেন যা একযোগে বিরামহীন সংগ্রাহক রয়েছে। আজুল জিঙের একটি "বিরতিহীন" সংগ্রাহক রয়েছে যা প্রকৃতপক্ষে বিরতিহীন তবে অত্যন্ত দ্রুত নয় যাতে কোনও লক্ষণীয় বিরতি নেই (এর জিসি বিরামগুলি অপারেটিং সিস্টেম থ্রেড কনটেক্সট সুইচ হিসাবে একই ক্রমে রয়েছে, যা সাধারণত বিরতি হিসাবে দেখা যায় না) ।
Jörg ডব্লু মিটাগ

14
(দীর্ঘ চলমান) সি ++ প্রোগ্রাম আমি ব্যবহার অধিকাংশই না মেমোরি ব্যবহার সময়ের unboundedly বৃদ্ধি আছে। আপনি কি একবারে কিছু দিনের বেশি অনুষ্ঠানের জন্য উন্মুক্ত থাকার অভ্যাসে থাকেন না?
জনাথন

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

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

26
What happens to garbage in C++? এটি কি সাধারণত সম্পাদনযোগ্য হিসাবে সংকলিত হয় না?
বিজে মায়ার্স

উত্তর:


100

প্রোগ্রামার নিশ্চিত যে বস্তু তারা মাধ্যমে তৈরি করা জন্য দায়ী newমাধ্যমে মুছে ফেলা হয় delete। যদি কোনও অবজেক্ট তৈরি করা হয় তবে শেষ পয়েন্টার বা রেফারেন্সের রেফারেশনের সুযোগের বাইরে যাওয়ার আগে এটি ধ্বংস না করা হয়, এটি ফাটলগুলির মধ্যে পড়ে এবং একটি মেমরি ফুটো হয়ে যায় ।

দুর্ভাগ্যক্রমে সি, সি ++ এবং অন্যান্য ভাষায় যা একটি জিসি অন্তর্ভুক্ত করে না, এটি সময়ের সাথে সহজভাবে পাইলস হয়ে যায়। এটি কোনও অ্যাপ্লিকেশন বা সিস্টেমকে মেমরির বাইরে চলে যাওয়ার কারণ হতে পারে এবং মেমরির নতুন ব্লকগুলি বরাদ্দ করতে অক্ষম হতে পারে। এই মুহুর্তে, ব্যবহারকারীকে অবশ্যই অ্যাপ্লিকেশনটি শেষ করতে অবলম্বন করতে হবে যাতে অপারেটিং সিস্টেমটি ব্যবহৃত মেমরিটিকে পুনরায় দাবি করতে পারে।

এই সমস্যাটি যতটা প্রশমিত করা যায়, এমন বেশ কয়েকটি জিনিস রয়েছে যা একটি প্রোগ্রামারের জীবনকে আরও সহজ করে তোলে। এগুলি প্রাথমিকভাবে সুযোগের প্রকৃতির দ্বারা সমর্থিত ।

int main()
{
    int* variableThatIsAPointer = new int;
    int variableInt = 0;

    delete variableThatIsAPointer;
}

এখানে আমরা দুটি ভেরিয়েবল তৈরি করেছি। কোঁকড়া ধনুর্বন্ধনী দ্বারা সংজ্ঞায়িত হিসাবে এগুলি ব্লক স্কোপে বিদ্যমান {}। যখন প্রয়োগটি এই সুযোগ থেকে সরে যায় তখন এই বিষয়গুলি স্বয়ংক্রিয়ভাবে মুছে ফেলা হবে। এই ক্ষেত্রে, variableThatIsAPointerএর নাম হিসাবে বোঝা যায়, স্মৃতিতে থাকা কোনও বস্তুর পয়েন্টার। যখন এটি সুযোগের বাইরে চলে যায়, পয়েন্টারটি মোছা হয়, তবে যে অবজেক্টটি এটি দেখায় তা অবশেষ। deleteকোনও স্মৃতি ফাঁস নেই তা নিশ্চিত করার জন্য এখানে আমরা এই বিষয়টিকে সুযোগের বাইরে চলে যাওয়ার আগেই এটি করি। তবে আমরা এই পয়েন্টারটি অন্য কোথাওও পেরিয়ে যেতে পারি এবং আশা করি এটি পরে মুছে ফেলা হবে।

এই সুযোগের প্রকৃতি শ্রেণিতে বিস্তৃত:

class Foo
{
public:
    int bar; // Will be deleted when Foo is deleted
    int* otherBar; // Still need to call delete
}

এখানে, একই নীতি প্রযোজ্য। আমাদের barকখন Fooমুছে ফেলা হবে তা নিয়ে চিন্তা করার দরকার নেই । তবে এর জন্য otherBar, কেবল পয়েন্টারটি মোছা হয়। যদি otherBarএটি কেবল যে কোনও বস্তুটির দিকে নির্দেশ করে তবে যদি এটি কেবলমাত্র বৈধ পয়েন্টার হয় তবে আমাদের সম্ভবত deleteএটির Fooডেস্ট্রাক্টরের মধ্যে থাকা উচিত । এটি আরআইআইয়ের পিছনে ড্রাইভিং ধারণা concept

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

আরআইআইআই হ'ল স্মার্ট পয়েন্টারগুলির পেছনের সাধারণ চালিকা শক্তি । সি ++ স্ট্যান্ডার্ড লাইব্রেরিতে, সেগুলি হল std::shared_ptr, std::unique_ptrএবং std::weak_ptr; যদিও আমি একই ধারণাগুলি অনুসরণ করে এমন অন্যান্য shared_ptr/ weak_ptrবাস্তবায়ন দেখেছি এবং ব্যবহার করেছি । এগুলির জন্য, একটি রেফারেন্স কাউন্টার কোনও প্রদত্ত বস্তুর জন্য কতগুলি পয়েন্টার রয়েছে তা সন্ধান করে এবং deleteএকবার এর সাথে আর কোনও রেফারেন্স না থাকলে সেটিকে স্বয়ংক্রিয়ভাবে বস্তুটি সরিয়ে দেয়।

এর বাইরেও, এটি সমস্ত প্রোগ্রামারের যথাযথ অনুশীলন এবং শৃঙ্খলায় নেমে আসে তা নিশ্চিত করার জন্য যে তাদের কোড সঠিকভাবে বস্তুগুলি পরিচালনা করে।


4
এর মাধ্যমে মুছে ফেলা হয়েছে delete- যা আমি খুঁজছিলাম তা ঠিক আছে। অসাধারণ.
জু শুয়া

3
আপনি সি ++ তে সরবরাহিত স্কোপিং মেকানিজমগুলি সম্পর্কে যুক্ত করতে চাইতে পারেন যা বেশিরভাগ নতুন এবং মুছে ফেলার সুযোগটি বেশিরভাগ-স্বয়ংক্রিয়ভাবে তৈরি করতে দেয়।
whatsisname

9
@ যে নামটি নতুন এবং মুছে ফেলা হয় তা স্বয়ংক্রিয়ভাবে তৈরি হয় না, এটি হ'ল এটি অনেক ক্ষেত্রেই ঘটে না
কালেথ

10
deleteস্বয়ংক্রিয়ভাবে দ্বারা আপনার জন্য বলা হয় স্মার্ট পয়েন্টার যদি আপনি তাদের ব্যবহার যাতে আপনি তাদের যে সময় ব্যবহার বিবেচনা করা উচিত একটি স্বয়ংক্রিয় স্টোরেজ ব্যবহার করা যাবে না যখন।
মারিয়ান স্প্যানিক

11
@ জুশুয়া নোট করুন যে আধুনিক সি ++ লেখার সময় deleteআপনার অ্যাপ্লিকেশন কোডটিতে আসলে কখনও আসার দরকার নেই (এবং সি ++ থেকে 14 এর পরে সমান হবে new), তবে পরিবর্তে স্মার্ট পয়েন্টার এবং আরআইআইআই ব্যবহার করে হিপ অবজেক্টগুলি মুছে ফেলা হবে। std::unique_ptrপ্রকার এবং std::make_uniqueফাংশন হ'ল অ্যাপ্লিকেশন কোড পর্যায়ে newএবং এর প্রত্যক্ষ, সহজ প্রতিস্থাপন delete
হাইড

82

সি ++ এর আবর্জনা সংগ্রহ নেই।

সি ++ অ্যাপ্লিকেশনগুলির নিজস্ব জঞ্জাল নিষ্পত্তি করতে হবে।

এটি বুঝতে সি ++ অ্যাপ্লিকেশন প্রোগ্রামারগুলির প্রয়োজন।

যখন তারা ভুলে যায়, ফলাফলটিকে "মেমরি ফাঁস" বলা হয়।


22
আপনি অবশ্যই নিশ্চিত করেছেন যে আপনার
উত্তরটিতে

15
@ বামফ্রন্টাবাউট: আপনাকে ধন্যবাদ আমি যে প্রশংসা বিবেচনা।
জন আর স্ট্রোহম

1
ঠিক আছে এই আবর্জনামুক্ত উত্তরের অনুসন্ধানে কীওয়ার্ড রয়েছে: মেমরি ফাঁস। এটি একরকম উল্লেখ করেও ভাল লাগবে newএবং delete
রুসলান

4
@Ruslan একই এছাড়াও প্রযোজ্য mallocএবং free, বা new[]এবং delete[]অন্য কোন allocators (উইন্ডোজ এর মত, অথবা GlobalAlloc, LocalAlloc, SHAlloc, CoTaskMemAlloc, VirtualAlloc, HeapAlloc, এবং মেমরি তোমার জন্য বরাদ্দ, ...) (যেমন মাধ্যমে fopen)।
ব্যবহারকারী 253751

43

সি, সি ++ এবং কোনও আবর্জনা সংগ্রাহক ব্যতীত অন্যান্য সিস্টেমে বিকাশকারীকে ভাষা এবং এর গ্রন্থাগারগুলি দ্বারা মেমরি কখন পুনরুদ্ধার করা যায় তা নির্দেশ করার জন্য সুবিধা দেওয়া হয়।

সর্বাধিক প্রাথমিক সুবিধা হ'ল স্বয়ংক্রিয় স্টোরেজ । অনেক সময়, ভাষা নিজেই নিশ্চিত করে যে আইটেমগুলি নিষ্পত্তি করা হয়:

int global = 0; // automatic storage

int foo(int a, int b) {
    static int local = 1; // automatic storage

    int c = a + b; // automatic storage

    return c;
}

এই ক্ষেত্রে, সংকলকটি কখন এই মানগুলি অব্যবহৃত হয় তা জানার দায়িত্বে থাকে এবং তাদের সাথে সম্পর্কিত স্টোরেজটি পুনরায় দাবি করে।

গতিশীল স্টোরেজ ব্যবহার করার সময় , সি তে, মেমরিটি traditionতিহ্যগতভাবে বরাদ্দ করা হয় mallocএবং এর সাথে পুনরায় দাবি করা হয় free। সি ++ তে মেমরিটি traditionতিহ্যগতভাবে বরাদ্দ করা হয় newএবং এর সাথে পুনরায় দাবি করা হয় delete

সি বছরের পর বছরগুলিতে খুব বেশি পরিবর্তন হয়নি, তবে আধুনিক সি ++ এচিউস newএবং deleteসম্পূর্ণরূপে এবং গ্রন্থাগারের সুবিধার পরিবর্তে (যা তারা নিজেরাই newএবং deleteযথাযথভাবে ব্যবহার করেন ) এর উপর নির্ভর করে :

  • স্মার্ট পয়েন্টারগুলি সর্বাধিক বিখ্যাত: std::unique_ptrএবংstd::shared_ptr
  • কিন্তু পাত্রে আরো অনেক কিছু ব্যাপক আসলে std::string, std::vector, std::map, ... সব অভ্যন্তরীণভাবে পরিবর্তনশীল বরাদ্দ পরিচালনা মেমরির স্বচ্ছভাবে

কথা বললে shared_ptr, একটি ঝুঁকি রয়েছে: যদি রেফারেন্সের একটি চক্র গঠিত হয়, এবং ভাঙা না হয়, তবে মেমোরি ফুটো হতে পারে। এই পরিস্থিতি এড়াতে বিকাশকারীদের উপর নির্ভর করে, shared_ptrপুরোপুরি এড়ানো সহজ উপায় এবং প্রকার স্তরে চক্র এড়ানো দ্বিতীয় সহজতম উপায় ।

ফলস্বরূপ মেমরি ফাঁস সি ++ তে কোনও সমস্যা নয় এমনকি নতুন ব্যবহারকারীদের জন্য যতক্ষণ না তারা ব্যবহার করা থেকে বিরত থাকে new, deleteবা std::shared_ptr। এটি সি এর বিপরীতে যেখানে কঠোর শৃঙ্খলা প্রয়োজনীয় এবং সাধারণত অপর্যাপ্ত।


তবে এই উত্তরটি মেমরি ফাঁসের দু'বোনকে উল্লেখ না করেই সম্পূর্ণ হবে না: ঝুঁকিপূর্ণ পয়েন্টার

ড্যাংলিং পয়েন্টার (বা ঝোলা রেফারেন্স) হ'ল একটি বিপত্তি যা কোনও পয়েন্টার বা রেফারেন্স রেখে মারা গেছে to উদাহরণ স্বরূপ:

int main() {
    std::vector<int> vec;
    vec.push_back(1);     // vec: [1]

    int& a = vec.back();

    vec.pop_back();       // vec: [], "a" is now dangling

    std::cout << a << "\n";
}

একটি ঝুঁকির পয়েন্টার বা রেফারেন্স ব্যবহার করা হচ্ছে অপরিজ্ঞাত আচরণ । সাধারণভাবে, ভাগ্যক্রমে, এটি একটি তাত্ক্ষণিক ক্রাশ; প্রায়শই, দুর্ভাগ্যক্রমে, এটি প্রথমে মেমরির দুর্নীতির কারণ হয় ... এবং সময়ে সময়ে অদ্ভুত আচরণের ক্রপ ঘটে কারণ সংকলকটি সত্যই অদ্ভুত কোডটি নির্গত করে।

প্রোগ্রামের সুরক্ষা / নির্ভুলতার দিক থেকে আজ অবধি সি এবং সি ++ এর সাথে অপরিজ্ঞাত আচরণটি সবচেয়ে বড় সমস্যা। আপনি কোনও আবর্জনা সংগ্রহকারী এবং কোনও অপরিজ্ঞাত আচরণ নয় এমন কোনও ভাষার জন্য মরিচা দেখতে চাইতে পারেন।


17
পুনঃ: "একটি ঝোলা পয়েন্টার বা রেফারেন্স ব্যবহার করা হচ্ছে অপরিজ্ঞাত আচরণ general যা আমার অভিজ্ঞতার সাথে মোটেও মেলে না; বিপরীতে, আমার অভিজ্ঞতাটি হ'ল ঝুঁকির পয়েন্টার ব্যবহার প্রায়শই কখনই তাত্ক্ষণিক ক্রাশের কারণ হয় না । । ।
রুখ

9
হ্যাঁ, যেহেতু একটি "পলক" হওয়ার জন্য কোনও পয়েন্টার অবশ্যই পূর্বের বরাদ্দকৃত মেমরিটিকে এক পর্যায়ে লক্ষ্যবস্তু করেছিল এবং সেই মেমরিটি সাধারণত প্রক্রিয়া থেকে সম্পূর্ণভাবে আনম্যাপ করা সম্ভব হয় না কারণ এটি আর অ্যাক্সেসযোগ্য নয়, কারণ এটি একটি হবে অবিলম্বে পুনঃব্যবহারের জন্য ভাল প্রার্থী ... অনুশীলনে, ঝুঁকিপূর্ণ পয়েন্টারগুলি ক্র্যাশ ঘটায় না, তারা বিশৃঙ্খলা সৃষ্টি করে।
লুশেনকো

2
"ফলস্বরূপ মেমরি ফাঁসের বিষয়টি সি ++ তে কোনও সমস্যা নয়," নিশ্চিত তারা হ'ল লাইব্রেরিগুলিতে স্ক্রু করার জন্য সি-র বাইন্ডিংগুলি পাশাপাশি রিকার্সিভ শেয়ারড_প্টারস এমনকি এমনকি পুনরাবৃত্তিয় ইউনিক_সিটার এবং অন্যান্য পরিস্থিতিতে রয়েছে।
মাকিং হাঁস

3
"সি ++ তে এমনকি নতুন ব্যবহারকারীদের জন্যও কোনও সমস্যা নয়" - আমি এটি "নতুন ব্যবহারকারী যারা জাভা-জাতীয় ভাষা বা সি থেকে আসে না " তাদের পক্ষে যোগ্যতা অর্জন করব

3
@leftaroundabout: এটা যোগ্যতাসম্পন্ন "যতদিন তারা ব্যবহার থেকে বিরত থাকুন হিসাবে new, deleteএবং shared_ptr"; ছাড়া newএবং shared_ptrআপনার সরাসরি মালিকানা রয়েছে তাই কোনও ফুটো নেই। অবশ্যই, আপনার ঝুঁকির পয়েন্টার ইত্যাদি থাকতে পারে ... তবে আমি ভয় করি যে এগুলি থেকে মুক্তি পেতে আপনার সি ++ ছাড়তে হবে।
ম্যাথিউ মিঃ

27

সি ++ এর এই জিনিসটিকে RAII বলা হয় । মূলত এর অর্থ হ'ল আবর্জনা পরিষ্কার হওয়ার সাথে সাথে আপনি এটি একটি গাদাতে রেখে রাখুন এবং ক্লিনারটি আপনার পরে পরিষ্কার রাখুন। (আমার ঘরে ফুটবল দেখার জন্য আমার কল্পনা করুন - আমি যেমন বিয়ারের ক্যান পান করি এবং নতুনের দরকার পড়ে, সি ++ উপায়টি হ'ল ফ্রিজে যাওয়ার পথে খালি ক্যানটি নিয়ে যাওয়া, সি # উপায়টি এটি মেঝেতে ফেলে রাখা হয়) এবং পরিস্কার করার জন্য কাজের মেয়েটি সেগুলি নেওয়ার অপেক্ষা করুন)।

এখন C ++ এ মেমরি ফাঁস করা সম্ভব, তবে এটির জন্য আপনাকে সাধারণ নির্মাণগুলি ছেড়ে দিয়ে কাজগুলি করার সি পদ্ধতিতে ফিরে যেতে হবে - মেমরির একটি ব্লক বরাদ্দ করা এবং কোনও ভাষার সহায়তা ব্যতীত সেই ব্লকটি কোথায় তা ট্র্যাক করা। কিছু লোক এই পয়েন্টারটিকে ভুলে যায় এবং তাই ব্লকটি সরাতে পারে না।


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

@ ডেভিডহ্যামেন নিশ্চিত, তবে এটি নিশ্চিত করার জন্য প্রায় প্রতিটি বস্তুর অনুসরণ করতে হবে। আপনার স্মার্ট পয়েন্টারগুলির উদাহরণটি এই বিষয়টিকে উপেক্ষা করে যে স্মার্ট পয়েন্টারটি নিজেই সুযোগের বাইরে চলে যাবে এবং তারপরে অবজেক্টগুলি মুক্ত হবে। আপনি ধরে নিন একটি স্মার্ট পয়েন্টারটি পয়েন্টারের মতো, এটি নয়, এটি এমন একটি বস্তু যা বেশিরভাগ পরামিতিগুলির মতো স্ট্যাকের চারপাশে পাস হয়। এটি জিসি ভাষাগুলিতে সৃষ্ট মেমরি ফাঁসের চেয়ে আলাদা নয় ,. উদাহরণস্বরূপ বিখ্যাত যেখানে কোনও ইউআই ক্লাস থেকে ইভেন্ট হ্যান্ডলারটি সরিয়ে ফেলা এটি নিঃশব্দে রেফারেন্স দেয় এবং তাই ফুটো হয়ে যায়।
gbjbaanb

1
স্মার্ট পয়েন্টার সাথে উদাহরণে @gbjbaanb, তন্ন তন্ন স্মার্ট পয়েন্টার কি কখনো পরিধি খুঁজে যায়, এটা কেন সেখানে একটি লিক আছে তা। যেহেতু উভয় স্মার্ট পয়েন্টার অবজেক্টগুলি একটি গতিশীল স্কোপগুলিতে বরাদ্দ করা হয়েছে , কোনও লেজিকাল নয়, তারা প্রত্যেকে ধ্বংস করার আগে অপরটির দিকে অপেক্ষা করার চেষ্টা করে। স্মার্ট পয়েন্টারগুলি সি ++ তে আসল অবজেক্ট এবং কেবল পয়েন্টারই নয় যে এখানে লিক হওয়ার কারণ হ'ল - স্ট্যাক স্কোপে অতিরিক্ত স্মার্ট পয়েন্টার অবজেক্টস যা কন্টেইনার অবজেক্টগুলিতেও নির্দেশ করেছিল তারা নিজেরাই যখন ধ্বংস করে দেয় কারণ তাদের পুনরায় গণনা করা হয় না নন-জিরো।
লুশেনকো

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

@ লুয়ান এটি একটি উপমা ছিল ... আমি মনে করি আপনি আরও খুশি হবেন যদি আমি বললাম যে এটি টেবিলের উপরে ক্যান রেখে দেয় যতক্ষণ না দাসী পরিষ্কার হয়ে আসে to
gbjbaanb

26

এটি লক্ষ করা উচিত যে এটি সি ++ এর ক্ষেত্রে একটি সাধারণ ভুল ধারণা যে "আপনাকে ম্যানুয়াল মেমরি পরিচালনা করতে হবে"। আসলে, আপনি সাধারণত আপনার কোডটিতে কোনও মেমরি পরিচালনা করেন না।

স্থির আকারের অবজেক্টস (স্কোপ আজীবন সহ)

যখন আপনার কোনও সামগ্রীর প্রয়োজন হয় তখন বেশিরভাগ ক্ষেত্রে, আপনার প্রোগ্রামে এই অবজেক্টটির একটি নির্দিষ্ট জীবনকাল থাকবে এবং এটি স্ট্যাকের উপরে তৈরি হবে। এটি সমস্ত অন্তর্নির্মিত আদিম ডেটা ধরণের জন্য কাজ করে, তবে ক্লাস এবং স্ট্রাক্টগুলির উদাহরণগুলির জন্যও:

class MyObject {
    public: int x;
};

int objTest()
{
    MyObject obj;
    obj.x = 5;
    return obj.x;
}

ফাংশন শেষ হয়ে গেলে স্ট্যাক অবজেক্টগুলি স্বয়ংক্রিয়ভাবে সরানো হয়। জাভাতে সর্বদা অবধি বস্তুগুলি তৈরি করা হয় এবং তাই আবর্জনা সংগ্রহের মতো কোনও প্রক্রিয়া দ্বারা মুছে ফেলতে হয়। এটি স্ট্যাক অবজেক্টগুলির জন্য একটি নন-ইস্যু।

গতিশীল ডেটা পরিচালনা করে এমন অবজেক্টস (স্কোপ লাইফটাইম সহ)

স্ট্যাকের স্থান ব্যবহার করা একটি নির্দিষ্ট আকারের অবজেক্টের জন্য কাজ করে। যখন আপনার অ্যারে হিসাবে চলক পরিমাণের প্রয়োজন হয়, তখন অন্য পদ্ধতির ব্যবহার করা হয়: তালিকাটি একটি স্থির আকারের বস্তুতে আবদ্ধ থাকে যা আপনার জন্য গতিশীল মেমরি পরিচালনা করে। এটি কাজ করে কারণ অবজেক্টগুলির একটি বিশেষ ক্লিনআপ ফাংশন থাকতে পারে ruct যখন বস্তুটি সুযোগের বাইরে চলে যায় এবং নির্ধারকের বিপরীতে থাকে তখন এটি কল করার নিশ্চয়তা দেওয়া হয়:

class MyList {        
public:
    // a fixed-size pointer to the actual memory.
    int* listOfInts; 
    // constructor: get memory
    MyList(size_t numElements) { listOfInts = new int[numElements]; }
    // destructor: free memory
    ~MyList() { delete[] listOfInts; }
};

int listTest()
{
    MyList list(1024);
    list.listOfInts[200] = 5;
    return list.listOfInts[200];
    // When MyList goes off stack here, its destructor is called and frees the memory.
}

যে কোডটিতে মেমরিটি ব্যবহৃত হয় সেখানে কোনও মেমরি পরিচালনা নেই। আমাদের কেবল এটি নিশ্চিত করতে হবে যে আমরা যে জিনিসটি লিখেছি তার উপযুক্ত ডেস্ট্রাক্টর রয়েছে। আমরা কীভাবে এই ক্ষেত্রটি ছেড়ে দিই না কেন listTest, এটি কোনও ব্যতিক্রমের মাধ্যমে বা কেবল এখান থেকে ফিরে আসার পরে, ধ্বংসকারীকে ~MyList()ডাকা হবে এবং আমাদের কোনও স্মৃতি পরিচালনা করার দরকার নেই।

(আমি মনে করি যে বাইনারি নট অপারেটরটি ~ব্যবহার করে, বিনষ্টকারীকে ইঙ্গিত করার জন্য এটি একটি মজার ডিজাইনের সিদ্ধান্ত on

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

বহুমুখী বস্তু এবং আধিপত্যের বাইরে

এখন, এই দুটি ক্ষেত্রেই ছিল স্মৃতির জন্য যা একটি স্পষ্টভাবে সংজ্ঞায়িত আজীবন রয়েছে: আজীবন সুযোগটি একই। আমরা যদি সুযোগটি ছাড়ার সময় কোনও বস্তুর মেয়াদ শেষ হতে না চাই, তৃতীয় প্রক্রিয়া রয়েছে যা আমাদের জন্য স্মৃতি পরিচালনা করতে পারে: একটি স্মার্ট পয়েন্টার। স্মার্ট পয়েন্টারগুলি তখনও ব্যবহৃত হয় যখন আপনি যখন অবজেক্টগুলির উদাহরণ রানটাইমের সময় পরিবর্তিত হয়ে থাকেন তবে এর মধ্যে একটি সাধারণ ইন্টারফেস বা বেস শ্রেণি থাকে:

class MyDerivedObject : public MyObject {
    public: int y;
};
std::unique_ptr<MyObject> createObject()
{
    // actually creates an object of a derived class,
    // but the user doesn't need to know this.
    return std::make_unique<MyDerivedObject>();
}

int dynamicObjTest()
{
    std::unique_ptr<MyObject> obj = createObject();
    obj->x = 5;
    return obj->x;
    // At scope end, the unique_ptr automatically removes the object it contains,
    // calling its destructor if it has one.
}

std::shared_ptrবেশ কয়েকটি ক্লায়েন্টের মধ্যে ভাগ করে নেওয়ার জন্য অন্য ধরণের স্মার্ট পয়েন্টার রয়েছে । শেষ ক্লায়েন্ট সুযোগের বাইরে চলে গেলে তারা কেবল তাদের অন্তর্ভুক্ত বস্তুটি মুছে দেয়, সুতরাং তাদের এমন পরিস্থিতিতে ব্যবহার করা যেতে পারে যেখানে কত ক্লায়েন্ট থাকবে এবং তারা কতক্ষণ অবজেক্টটি ব্যবহার করবে এটি সম্পূর্ণ অজানা।

সংক্ষেপে, আমরা দেখতে পাই যে আপনি সত্যিই কোনও ম্যানুয়াল মেমরি পরিচালনা করেন না do সমস্ত কিছু এনক্যাপসুলেটেড হয় এবং তারপরে সম্পূর্ণ স্বয়ংক্রিয়, স্কোপ-ভিত্তিক মেমরি পরিচালনার মাধ্যমে যত্ন নেওয়া হয়। যে ক্ষেত্রে এটি পর্যাপ্ত নয়, সেখানে স্মার্ট পয়েন্টার ব্যবহার করা হয় যা কাঁচা মেমরিকে আবৃত করে।

সি ++ কোডের যে কোনও জায়গায় রিসোর্স মালিক হিসাবে কাঁচা পয়েন্টার ব্যবহার করা, নির্মাতাদের বাইরে কাঁচা বরাদ্দ এবং deleteডেস্ট্রাক্টরের বাইরে কাঁচা কলগুলি ব্যবহার করা চূড়ান্ত খারাপ অনুশীলন হিসাবে বিবেচিত হয় , কারণ ব্যতিক্রমগুলি দেখা দেওয়ার সময় তারা পরিচালনা করা প্রায় অসম্ভব এবং সাধারণত নিরাপদে ব্যবহার করা শক্ত।

সেরা: এটি সমস্ত ধরণের সংস্থার জন্য কাজ করে

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

উদাহরণস্বরূপ, একটি মিউটেক্স লক করা একটি ফাংশন সাধারণত সি ++ এ লেখা হয়:

void criticalSection() {
    std::scoped_lock lock(myMutex); // scoped_lock locks the mutex
    doSynchronizedStuff();
} // myMutex is released here automatically

অন্য ভাষাগুলি এটিকে আরও জটিল করে তোলে, হয় আপনাকে ম্যানুয়ালি এই কাজটি করার প্রয়োজন হয় (উদাহরণস্বরূপ একটি finallyঅনুচ্ছেদে) অথবা তারা বিশেষায়িত প্রক্রিয়া উদ্ভাবন করে যা এই সমস্যাটি সমাধান করে, তবে বিশেষভাবে মার্জিত উপায়ে নয় (সাধারণত তাদের জীবনে পরে যখন যথেষ্ট লোক থাকে) সংকট থেকে ভোগা)। এই জাতীয় প্রক্রিয়াগুলি জাভাতে রিসোর্সগুলি চেষ্টা করে এবং সি # তে ব্যবহারের বিবৃতি, উভয়ই সি ++ এর আরআইআইয়ের অনুমান।

সুতরাং, সংক্ষেপে বলতে গেলে, এগুলি সমস্তই সি ++ এ আরআইআইয়ের একটি অতি পৃষ্ঠপোষক বিবরণ ছিল, তবে আমি আশা করি এটি পাঠকদের বুঝতে সহায়তা করে যে মেমরি এবং এমনকি সি ++ এ রিসোর্স পরিচালনা সাধারণত "ম্যানুয়াল" নয়, তবে বেশিরভাগই স্বয়ংক্রিয়ভাবে স্বয়ংক্রিয়।


7
এটিই একমাত্র উত্তর যা লোকেদের ভুল তথ্য দেয় না বা সি ++ আঁকায় না যা সত্যিকারের চেয়ে বেশি কঠিন বা বিপজ্জনক।
আলেকজান্ডার রেভো

6
বিটিডাব্লু, এটি কেবলমাত্র সংস্থার মালিক হিসাবে কাঁচা পয়েন্টার ব্যবহার করা খারাপ অভ্যাস হিসাবে বিবেচিত হয়। এগুলি ব্যবহার করার ক্ষেত্রে কোনও ভুল নেই কারণ যদি তারা এমন কোনও কিছুকে নির্দেশ করে যা নিজেই পয়েন্টারের বাইরে চলে যাওয়ার গ্যারান্টিযুক্ত।
আলেকজান্ডার রেভো

8
আমি দ্বিতীয় আলেকজান্ডার। "সি ++ এর কোনও স্বয়ংক্রিয় মেমরি পরিচালনা নেই, deleteআপনি একটি ভুলে যান এবং আপনি মারা গেছেন" তা দেখে আমি অবাক হয়ে গেলাম উত্তরগুলি 30 টি পয়েন্টের ওপরে রকেটিং করে গ্রহণযোগ্য হবে, যখন এইটির পাঁচটি রয়েছে। কেউ কি এখানে আসলে সি ++ ব্যবহার করে?
কোয়ান্টিন

8

বিশেষত সি এর প্রতি শ্রদ্ধা সহ, ভাষা আপনাকে গতিময় বরাদ্দ মেমরি পরিচালনা করার জন্য কোনও সরঞ্জাম দেয় না। প্রত্যেকেরই কোথাও *allocকোনওরকম freeকোনও সম্পর্ক রয়েছে কিনা তা নিশ্চিত করার জন্য আপনি একেবারে দায়বদ্ধ ।

জিনিসগুলি যেখানে খুব খারাপ লাগে তখন যখন কোনও সংস্থার বরাদ্দ মাঝের মাঝখানে ব্যর্থ হয়; আপনি কি আবার চেষ্টা করেন, আপনি কি আবার পিছন ফিরে রোল এবং শুরু থেকেই শুরু করেন, আপনি কি আবার রোল দিয়ে একটি ত্রুটি নিয়ে প্রস্থান করেন, আপনি কি কেবল খালি জামিন করেন এবং ওএসকে এটি মোকাবেলা করতে দেন?

উদাহরণস্বরূপ, একটি অ-সংগতিপূর্ণ 2D অ্যারে বরাদ্দ করার জন্য এখানে একটি ফাংশন। এখানে আচরণটি হ'ল যদি প্রক্রিয়াটির মাঝামাঝি সময়ে যদি কোনও বরাদ্দ ব্যর্থতা দেখা দেয় তবে আমরা সমস্ত কিছু পিছনে ফেরা করি এবং একটি ন্যূনাল পয়েন্টার ব্যবহার করে একটি ত্রুটি সূচক ফিরে পাই:

/**
 * Allocate space for an array of arrays; returns NULL
 * on error.
 */
int **newArr( size_t rows, size_t cols )
{
  int **arr = malloc( sizeof *arr * rows );
  size_t i;

  if ( arr ) // malloc returns NULL on failure
  {
    for ( i = 0; i < rows; i++ )
    {
      arr[i] = malloc( sizeof *arr[i] * cols );
      if ( !arr[i] )
      {
        /**
         * Whoopsie; we can't allocate any more memory for some reason.
         * We can't just return NULL at this point since we'll lose access
         * to the previously allocated memory, so we branch to some cleanup
         * code to undo the allocations made so far.  
         */
        goto cleanup;
      }
    }
  }
  goto done;

/**
 * We encountered a failure midway through memory allocation,
 * so we roll back all previous allocations and return NULL.
 */
cleanup:
  while ( i )         // this is why we didn't limit the scope of i to the for loop
    free( arr[--i] ); // delete previously allocated rows
  free( arr );        // delete arr object
  arr = NULL;

done:
  return arr;
}

এই কোডটি সেগুলির সাথে বাজে -কুৎসিতgoto , তবে কোনও কাঠামোগত ব্যতিক্রম হ্যান্ডলিং প্রক্রিয়াটির অনুপস্থিতিতে, পুরোপুরি জামিন না দিয়ে সমস্যাটি মোকাবেলা করার এটি একমাত্র উপায়, বিশেষত যদি আপনার সংস্থান বরাদ্দ কোডটি আরও নিস্ট করা থাকে এক লুপ গভীর। এটি খুব অল্প সময়ের মধ্যে একটি যেখানে gotoপ্রকৃতপক্ষে একটি আকর্ষণীয় বিকল্প; অন্যথায় আপনি একগুচ্ছ পতাকা এবং অতিরিক্ত ifবিবৃতি ব্যবহার করছেন ।

আপনি প্রতিটি উত্সের জন্য উত্সর্গীকৃত বরাদ্দক / ডেলোকেটর ফাংশন লিখে নিজের জীবনকে আরও সহজ করে তুলতে পারেন

Foo *newFoo( void )
{
  Foo *foo = malloc( sizeof *foo );
  if ( foo )
  {
    foo->bar = newBar();
    if ( !foo->bar ) goto cleanupBar;
    foo->bletch = newBletch(); 
    if ( !foo->bletch ) goto cleanupBletch;
    ...
  }
  goto done;

cleanupBletch:
  deleteBar( foo->bar );
  // fall through to clean up the rest

cleanupBar:
  free( foo );
  foo = NULL;

done:
  return foo;
}

void deleteFoo( Foo *f )
{
  deleteBar( f->bar );
  deleteBletch( f->bletch );
  free( f );
}

1
এটি gotoবিবৃতি সহ একটি ভাল উত্তর । এটি কিছু ক্ষেত্রে অনুশীলন করার পরামর্শ দেওয়া হচ্ছে। এটি সি এর ব্যতিক্রমগুলির সমতুল্যতা থেকে রক্ষা করার জন্য একটি সাধারণভাবে ব্যবহৃত স্কিম, লিনাক্স কার্নেল কোডটি দেখুন, যা gotoবিবৃতিতে পূর্ণ - এবং যা ফুটো হয় না।
ডেভিড হামেন

"কেবল পুরোপুরি জামিন না দিয়ে" -> ন্যায্যতায়, আপনি যদি সি সম্পর্কে কথা বলতে চান তবে এটি সম্ভবত ভাল অভ্যাস। সি হ'ল মেমোরির ব্লকগুলি হ্যান্ডল করার জন্য যেটি অন্য কোথাও থেকে এসেছে, বা স্মৃতিতে ছোট ছোট অংশগুলি অন্য পদ্ধতিতে পার্সেলিংয়ের জন্য সবচেয়ে ভাল ব্যবহৃত একটি ভাষা , তবে উভয়ই একই সাথে আন্তঃবিবাহিত পদ্ধতিতে না করাই ভাল। আপনি যদি সিটিতে ধ্রুপদী "অবজেক্টস" ব্যবহার করেন তবে আপনি সম্ভবত ভাষাটিকে তার শক্তিতে ব্যবহার করছেন না।
লুশেনকো

দ্বিতীয়টি gotoবহিরাগত। যদি আপনি পরিবর্তিত এটা আরো পাঠযোগ্য হতে চাই goto done;থেকে return arr;এবং arr=NULL;done:return arr;থেকে return NULL;। যদিও আরও জটিল ক্ষেত্রে সত্যিকারের gotoবিভিন্ন স্তরে তালিকাভুক্ত হওয়া শুরু করে একাধিক গুলি থাকতে পারে (সি ++ এ আন-বাইন্ডিং ব্যতিক্রম ব্যতীত কী হবে)।
রুসলান

2

আমি বিভিন্ন বিভিন্ন বিভাগে মেমরির বিষয়গুলি শ্রেণিবদ্ধ করতে শিখেছি।

  • এক সময় ড্রিপস। ধরুন কোনও প্রোগ্রাম শুরুর সময় 100 বাইট ফাঁস করে দেয়, কেবল কখনও আর ফুটো করা যায় না। এই এক-সময় ফাঁসের পিছনে তাড়া করা এবং তা অপসারণ করা দুর্দান্ত (আমি লিক সনাক্তকরণের সক্ষমতা দ্বারা পরিষ্কার প্রতিবেদন করা পছন্দ করি) তবে এটি অপরিহার্য নয়। কখনও কখনও আরও বড় সমস্যাগুলির উপর আক্রমণ করা প্রয়োজন।

  • বার বার ফাঁস। একটি ক্রিয়াকলাপ যা পুনরাবৃত্তিভাবে বলা হয় একটি প্রোগ্রামের সময়কালে জীবনকাল যা নিয়মিত স্মৃতি ফাঁস করে একটি বড় সমস্যা। এই ড্রিপগুলি প্রোগ্রামটিকে এবং সম্ভবত ওএসকে মৃত্যুর জন্য নির্যাতন করবে।

  • পারস্পরিক রেফারেন্স। যদি ভাগ করা পয়েন্টারগুলির মাধ্যমে অবজেক্টস এ এবং বি একে অপরকে রেফারেন্স করে তবে আপনাকে সেগুলি ক্লাসের ডিজাইনে বা কোডটি প্রয়োগ করে / বৃত্তাকারতা ভেঙে সেই ক্লাসগুলি ব্যবহার করে এমন কিছু করতে হবে। (আবর্জনা সংগ্রহ করা ভাষার ক্ষেত্রে এটি কোনও সমস্যা নয়))

  • খুব বেশি মনে আছে। এটাই আবর্জনা / স্মৃতি ফুটো হওয়ার দুষ্ট কাজিন। আরআইআই এখানে সহায়তা করবে না, আবর্জনা সংগ্রহও করবে না। এটি যে কোনও ভাষায় সমস্যা। যদি কিছু সক্রিয় ভেরিয়েবলের এমন একটি পথ থাকে যা এটিকে মেমোরির কিছু এলোমেলো সংযোগের সাথে সংযুক্ত করে, মেমরির এলোমেলো অংশ আবর্জনা নয়। একটি প্রোগ্রাম বানানো ভুলে যাওয়া হয়ে ওঠে যাতে এটি বেশ কয়েক দিন চলতে পারে। এমন একটি প্রোগ্রাম তৈরি করা যা বেশ কয়েক মাস ধরে চলতে পারে (উদাহরণস্বরূপ, ডিস্ক ব্যর্থ হওয়া অবধি) খুব জটিল।

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


-6

এটি প্রয়োজনীয় যেখানে প্রয়োজন তার নিজের ফর্ম আবর্জনা সংগ্রহের সি ++ প্রোগ্রামার উপর নির্ভর করে। এটি করতে ব্যর্থ হওয়ার ফলে 'মেমরি ফাঁস' বলা হয়। 'উচ্চ স্তরের' ভাষাগুলির জন্য (যেমন জাভা) আবর্জনা সংগ্রহের ক্ষেত্রে তৈরি করা বেশ সাধারণ, তবে 'নিম্ন স্তরের' ভাষা যেমন সি এবং সি ++ না করে।

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