গতিশীল বরাদ্দ কেবল তখনই প্রয়োজন যখন অবজেক্টের আয়ু-সময়টি তৈরি হওয়ার সুযোগের চেয়ে আলাদা হওয়া উচিত (এটি ক্ষেত্রকে আরও বৃহত্তর করে তোলার জন্য এটি ধারণ করে) এবং আপনার কাছে একটি নির্দিষ্ট কারণ আছে যেখানে এটি মান দ্বারা সঞ্চয় করে না হবে।
উদাহরণ স্বরূপ:
std::vector<int> *createVector(); // Bad
std::vector<int> createVector(); // Good
auto v = new std::vector<int>(); // Bad
auto result = calculate(/*optional output = */ v);
auto v = std::vector<int>(); // Good
auto result = calculate(/*optional output = */ &v);
সি ++ 11 থেকে, আমাদের std::unique_ptr
বরাদ্দ মেমরির সাথে কাজ করার জন্য রয়েছে, যা বরাদ্দ মেমরির মালিকানা ধারণ করে। std::shared_ptr
যখন আপনাকে মালিকানা ভাগ করতে হবে তখনই তৈরি হয়েছিল। (একটি ভাল প্রোগ্রামে আপনি যেটা আশা করবেন তার চেয়ে কম আপনার প্রয়োজন হবে)
একটি উদাহরণ তৈরি করা সত্যিই সহজ হয়ে যায়:
auto instance = std::make_unique<Class>(/*args*/); // C++14
auto instance = std::make_unique<Class>(new Class(/*args*/)); // C++11
auto instance = std::make_unique<Class[]>(42); // C++14
auto instance = std::make_unique<Class[]>(new Class[](42)); // C++11
সি ++ 17 এছাড়াও যুক্ত করে std::optional
যা আপনাকে মেমরির বরাদ্দের প্রয়োজনীয়তা থেকে বাধা দিতে পারে
auto optInstance = std::optional<Class>{};
if (condition)
optInstance = Class{};
'উদাহরণ' সুযোগের বাইরে যাওয়ার সাথে সাথে স্মৃতিশক্তি পরিষ্কার হয়ে যায়। মালিকানা স্থানান্তর করাও সহজ:
auto vector = std::vector<std::unique_ptr<Interface>>{};
auto instance = std::make_unique<Class>();
vector.push_back(std::move(instance)); // std::move -> transfer (most of the time)
তাহলে আপনার এখনও কখন দরকার new
? প্রায় কখনও সি ++ 11 থেকে নেই। আপনি বেশিরভাগই std::make_unique
এমন কোনও বিন্দুতে না পৌঁছা পর্যন্ত ব্যবহার করেন যেখানে আপনি কাঁচা পয়েন্টারগুলির মাধ্যমে মালিকানা স্থানান্তর করে এমন একটি এআইপি মারেন।
auto instance = std::make_unique<Class>();
legacyFunction(instance.release()); // Ownership being transferred
auto instance = std::unique_ptr<Class>{legacyFunction()}; // Ownership being captured in unique_ptr
সি ++ 98/03 এ আপনাকে ম্যানুয়াল মেমরি পরিচালনা করতে হবে। আপনি যদি এই ক্ষেত্রে থাকেন তবে মানকটির আরও সাম্প্রতিক সংস্করণে আপগ্রেড করার চেষ্টা করুন। যদি আপনি আটকে থাকেন:
auto instance = new Class(); // Allocate memory
delete instance; // Deallocate
auto instances = new Class[42](); // Allocate memory
delete[] instances; // Deallocate
কোনও মেমরি ফাঁস না হওয়ার জন্য আপনি মালিকানাটি সঠিকভাবে ট্র্যাক করেছেন তা নিশ্চিত করুন! সরানো শব্দার্থবিজ্ঞানগুলি এখনও কাজ করে না।
সুতরাং, যখন আমাদের সি ++ এ ম্যালোক প্রয়োজন? একমাত্র বৈধ কারণ হ'ল মেমরি বরাদ্দ করা এবং পরে নতুন স্থাপনার মাধ্যমে এটিকে আরম্ভ করা।
auto instanceBlob = std::malloc(sizeof(Class)); // Allocate memory
auto instance = new(instanceBlob)Class{}; // Initialize via constructor
instance.~Class(); // Destroy via destructor
std::free(instanceBlob); // Deallocate the memory
যদিও উপরেরটি বৈধ, এটি একটি নতুন অপারেটরের মাধ্যমেও করা যেতে পারে। std::vector
এটির জন্য একটি ভাল উদাহরণ।
পরিশেষে, আমরা এখনো রুমে হাতি আছে: C
। আপনার যদি এমন সি-লাইব্রেরি নিয়ে কাজ করতে হয় যেখানে মেমরিটি সি ++ কোডে বরাদ্দ হয়ে যায় এবং সি কোডে (বা অন্য উপায়ে) মুক্ত হয় তবে আপনাকে ম্যালোক / ফ্রি ব্যবহার করতে বাধ্য করা হবে।
আপনি যদি এই ক্ষেত্রে থাকেন তবে ভার্চুয়াল ফাংশন, সদস্য ফাংশন, ক্লাসগুলি সম্পর্কে ভুলে যান ... কেবলমাত্র এতে POD সহ স্ট্রাক্টের অনুমতি রয়েছে।
নিয়মের কিছু ব্যতিক্রম:
- আপনি উন্নত ডেটা স্ট্রাকচার সহ একটি স্ট্যান্ডার্ড লাইব্রেরি লিখছেন যেখানে malloc উপযুক্ত
- আপনাকে বড় পরিমাণে মেমরি বরাদ্দ করতে হবে (10 জিবি ফাইলের মেমরি অনুলিপিটিতে?)
- আপনার নির্দিষ্ট সরঞ্জাম ব্যবহার করতে বাধা দেওয়ার সরঞ্জাম রয়েছে
- আপনার একটি অসম্পূর্ণ প্রকার সংরক্ষণ করতে হবে