আমি সি ++ প্রোগ্রামগুলিতে মেমরি ফাঁস করি না তা নিশ্চিত করার জন্য কয়েকটি সাধারণ টিপস কী? গতিশীলরূপে বরাদ্দ করা হয়েছে এমন কাকে মুক্ত করতে হবে তা আমি কীভাবে আবিষ্কার করব?
আমি সি ++ প্রোগ্রামগুলিতে মেমরি ফাঁস করি না তা নিশ্চিত করার জন্য কয়েকটি সাধারণ টিপস কী? গতিশীলরূপে বরাদ্দ করা হয়েছে এমন কাকে মুক্ত করতে হবে তা আমি কীভাবে আবিষ্কার করব?
উত্তর:
ম্যানুয়ালি ম্যানুয়ালি পরিচালনা করার পরিবর্তে, প্রযোজ্য যেখানে স্মার্ট পয়েন্টার ব্যবহার করার চেষ্টা করুন।
কটাক্ষপাত বুস্ট liberal এর সংক্ষিপ্ত রূপ , TR1 , এবং স্মার্ট পয়েন্টার ।
এছাড়াও স্মার্ট পয়েন্টারগুলি এখন সি ++ স্ট্যান্ডার্ডের সি ++ 11 নামক একটি অংশ ।
আমি আরআইআই এবং স্মার্ট পয়েন্টার সম্পর্কিত সমস্ত পরামর্শের পুরোপুরি সমর্থন করি, তবে আমি কিছুটা উচ্চ-স্তরের টিপও যুক্ত করতে চাই: পরিচালনা করার পক্ষে সবচেয়ে সহজ মেমরিটি আপনি কখনই বরাদ্দ করেননি memory সি # এবং জাভা এর মতো ভাষার মতো নয়, যেখানে বেশ কিছু সবকিছুই একটি রেফারেন্স, সি ++ এ আপনি যখনই পারেন ততক্ষণ স্ট্যাকগুলিতে রাখা উচিত। যেহেতু আমি বেশিরভাগ লোককে (ডাঃ স্ট্রাস্ট্রাপ সহ) দেখিয়েছি, আবর্জনা সংগ্রহ সি ++ এ কখনও জনপ্রিয় না হওয়ার মূল কারণ হ'ল সু-লিখিত সি ++ প্রথম স্থানটিতে খুব বেশি আবর্জনা তৈরি করে না।
লিখবেন না
Object* x = new Object;
অথবা এমনকি
shared_ptr<Object> x(new Object);
আপনি যখন লিখতে পারেন
Object x;
এই পোস্টটি পুনরাবৃত্তি বলে মনে হচ্ছে, তবে সি ++ এ, জানা সবচেয়ে প্রাথমিক প্যাটার্নটি হল RAII ।
স্মার্ট পয়েন্টারগুলি ব্যবহার করতে শিখুন, উভয়ই বুস্ট, টিআর 1 বা এমনকি নিম্নমানের (তবে প্রায়শই যথেষ্ট দক্ষ) অটো_পিটার (তবে আপনাকে অবশ্যই এর সীমাবদ্ধতাগুলি জানতে হবে)।
আরআইআই হ'ল সি ++ এ ব্যতিক্রমী সুরক্ষা এবং সংস্থান নিষ্পত্তি উভয়ের ভিত্তি, এবং অন্য কোনও প্যাটার্ন (স্যান্ডউইচ, ইত্যাদি) আপনাকে উভয়ই দেবে না (এবং বেশিরভাগ সময় এটি আপনাকে কিছুই দেয় না)।
নীচে RAII এবং অ RAII কোডের তুলনা দেখুন:
void doSandwich()
{
T * p = new T() ;
// do something with p
delete p ; // leak if the p processing throws or return
}
void doRAIIDynamic()
{
std::auto_ptr<T> p(new T()) ; // you can use other smart pointers, too
// do something with p
// WON'T EVER LEAK, even in case of exceptions, returns, breaks, etc.
}
void doRAIIStatic()
{
T p ;
// do something with p
// WON'T EVER LEAK, even in case of exceptions, returns, breaks, etc.
}
সংক্ষিপ্তসার হিসাবে ( ওগ্রে গীতসংহিতা 33 এর মন্তব্যের পরে ), আরআইআই তিনটি ধারণার উপর নির্ভর করে:
এর অর্থ হ'ল সঠিক সি ++ কোডে বেশিরভাগ অবজেক্টগুলি নির্মাণ করা হবে না new
এবং পরিবর্তে স্ট্যাকের উপরে ঘোষণা করা হবে। এবং ব্যবহার করে নির্মিত তাদের জন্য new
, সমস্ত কিছু হ'ল স্কোপড (উদাহরণস্বরূপ স্মার্ট পয়েন্টারের সাথে সংযুক্ত)।
একজন বিকাশকারী হিসাবে, এটি সত্যই শক্তিশালী যেহেতু আপনাকে ম্যানুয়াল রিসোর্স হ্যান্ডলিং (সি-তে যেমন করা হয়েছে, বা জাভাতে এমন কিছু বিষয় যা এই ক্ষেত্রে try
/ এর নিবিড় ব্যবহার করে finally
) সম্পর্কে যত্ন নেওয়ার দরকার নেই ...
"স্কোপড অবজেক্টস ... ধ্বংস হবে ... প্রস্থানটি কোনও ব্যাপার নয়" এটি সম্পূর্ণ সত্য নয়। RAII কে প্রতারণা করার উপায় রয়েছে। সমাপ্তির কোনও স্বাদ () ক্লিনআপকে বাইপাস করবে। প্রস্থান (EXIT_SUCCESS) এই ক্ষেত্রে একটি অক্সিমারন।
উইলহেমটেল এ সম্পর্কে বেশ সঠিক: রাইআইআই কে প্রতারণা করার ব্যতিক্রমী উপায় রয়েছে, যা প্রক্রিয়াটি হঠাৎ করে থামিয়ে দেয় leading
সেগুলি ব্যতিক্রমী উপায় কারণ সি ++ কোডটি টার্মিনেট, প্রস্থান ইত্যাদি দ্বারা ফাঁকানো হয় না বা ব্যতিক্রমগুলির ক্ষেত্রে, আমরা প্রক্রিয়াটি ক্র্যাশ করার জন্য একটি অনিচ্ছাকৃত ব্যতিক্রম চাই এবং কোরটির মেমরি চিত্রটি যেমন আছে তেমন পরিষ্কার করার পরে নয়।
তবে আমাদের অবশ্যই এখনও এই মামলাগুলি সম্পর্কে জানতে হবে কারণ এগুলি খুব কমই ঘটেছিল, তবুও তারা ঘটতে পারে।
(কে ফোন করেছেন terminate
বা exit
নৈমিত্তিক সি ++ কোডে? ... আমার মনে আছে জিএলইউটি দিয়ে খেলতে গিয়ে এই সমস্যার সাথে মোকাবিলা করতে হয়েছিল : এই লাইব্রেরিটি সি সি ++ বিকাশকারীদের পক্ষে যত্নশীল না করার মতো বিষয়টিকে সক্রিয়ভাবে নকশাকৃত করে গড়ে তোলা হয়েছে design সম্পর্কে স্ট্যাক বরাদ্দ তথ্য , বা সম্পর্কে "আকর্ষণীয়" সিদ্ধান্ত থাকার কখনো তাদের প্রধান লুপ থেকে ফিরে ... আমি যে বিষয়ে মন্তব্য না) ।
আপনি বুস্টের স্মার্ট পয়েন্টারগুলির মতো স্মার্ট পয়েন্টারগুলি দেখতে চাইবেন ।
পরিবর্তে
int main()
{
Object* obj = new Object();
//...
delete obj;
}
রেফারেন্স গণনা শূন্য হওয়ার পরে শেয়ারড_প্টার স্বয়ংক্রিয়ভাবে মোছা হবে:
int main()
{
boost::shared_ptr<Object> obj(new Object());
//...
// destructor destroys when reference count is zero
}
আমার শেষ নোটটি নোট করুন, "যখন রেফারেন্স গণনাটি শূন্য হয়, যা সবচেয়ে দুর্দান্ত অংশ So সুতরাং আপনার যদি অবজেক্টের একাধিক ব্যবহারকারী থাকে তবে আপনাকে এখনও অবজেক্টটি ব্যবহার হচ্ছে কিনা সে সম্পর্কে আপনার নজর রাখতে হবে না Once একবার কেউ আপনার উল্লেখ না করে ভাগ করা পয়েন্টার, এটি ধ্বংস হয়ে যায়।
তবে এটি কোনও প্যানাসিয়া নয়। যদিও আপনি বেস পয়েন্টারটি অ্যাক্সেস করতে পারবেন তবে আপনি এটির কোনও তৃতীয় পক্ষের API এ পাস করতে চাইবেন না যদি না আপনি এটি করছেন যা নিয়ে বিশ্বাস না করে। প্রচুর সময়, তৈরির সুযোগ শেষ হওয়ার পরে কাজ শেষ হওয়ার জন্য আপনার "পোস্টিং" স্টাফটি অন্য কোনও থ্রেডে করে। এটি উইন 32-এ পোস্টথ্রেডম্যাসেজের সাথে সাধারণ:
void foo()
{
boost::shared_ptr<Object> obj(new Object());
// Simplified here
PostThreadMessage(...., (LPARAM)ob.get());
// Destructor destroys! pointer sent to PostThreadMessage is invalid! Zohnoes!
}
বরাবরের মতো, আপনার চিন্তাভাবনা ক্যাপটি কোনও সরঞ্জাম দিয়ে ব্যবহার করুন ...
বেশিরভাগ স্মৃতি ফাঁস হ'ল অবজেক্টের মালিকানা এবং আজীবন সম্পর্কে পরিষ্কার না হওয়ার ফলাফল are
প্রথম কাজটি হ'ল স্ট্যাকের উপর বরাদ্দ করা যখনই আপনি পারেন। এটি বেশিরভাগ ক্ষেত্রেই আপনাকে মোকাবেলা করে যেখানে কোনও উদ্দেশ্যে কোনও একক বস্তু বরাদ্দ করতে হবে।
যদি আপনার কোনও অবজেক্ট 'নতুন' করার দরকার হয় তবে বেশিরভাগ সময় এর বাকী জীবনকালগুলির একক সুস্পষ্ট মালিক থাকবেন। এই পরিস্থিতির জন্য আমি সংক্ষেপে টেমপ্লেটগুলির একটি গুচ্ছ ব্যবহার করার ঝোঁক ব্যবহার করি যা পয়েন্টার অনুসারে তাদের সংরক্ষণ করা অবজেক্টগুলিকে 'মালিকানা' দেওয়ার জন্য তৈরি করা হয়েছে। এগুলি এসটিএল ভেক্টর এবং মানচিত্রের ধারকগুলির সাথে প্রয়োগ করা হলেও এতে কিছু পার্থক্য রয়েছে:
এসটিএল সহ আমার বিফটি হ'ল এটি ভ্যালু অবজেক্টগুলির উপর এত বেশি কেন্দ্রীভূত হয় যখন বেশিরভাগ অ্যাপ্লিকেশনে অবজেক্টগুলি অনন্য সত্তা থাকে যেখানে সেই ধারকগুলিতে ব্যবহারের জন্য অর্থপূর্ণ অনুলিপি শব্দার্থবিজ্ঞান থাকে না।
বাহ, আপনি বাচ্চাদের বাচ্চাদের এবং আপনার নতুন-জঞ্জাল আবর্জনা সংগ্রহকারী ...
"মালিকানা" সম্পর্কে খুব শক্তিশালী নিয়ম - কোন বিষয় বা সফ্টওয়্যারটির অংশটি অবজেক্টটি মোছার অধিকার রাখে। কোনও পয়েন্টারটি "মালিকানাধীন" বা "কেবল চেহারা, স্পর্শ করবেন না" তা স্পষ্ট করার জন্য পরিষ্কার মন্তব্য এবং বুদ্ধিমান পরিবর্তনশীল নামগুলি পরিষ্কার করুন। কার কী মালিক তা সিদ্ধান্তে সহায়তা করতে প্রতিটি সাব্রোটিন বা পদ্ধতির মধ্যে যথাসম্ভব "স্যান্ডউইচ" প্যাটার্নটি অনুসরণ করুন।
create a thing
use that thing
destroy that thing
কখনও কখনও এটি বিভিন্ন জায়গায় বিভিন্ন জায়গায় তৈরি করা এবং ধ্বংস করা প্রয়োজন; আমি এড়াতে কঠিন মনে করি।
জটিল ডাটা স্ট্রাকচারের প্রয়োজন হয় এমন যে কোনও প্রোগ্রামে আমি "মালিক" পয়েন্টার ব্যবহার করে অন্যান্য অবজেক্টযুক্ত বস্তুর একটি কঠোর পরিষ্কার কাটা গাছ তৈরি করি। এই ট্রি অ্যাপ্লিকেশন ডোমেন ধারণাগুলির প্রাথমিক স্তরক্রমকে মডেল করে। উদাহরণস্বরূপ একটি 3 ডি দৃশ্যে অবজেক্টস, লাইট, টেক্সচারের মালিকানা রয়েছে। প্রোগ্রামটি বন্ধ হয়ে গেলে রেন্ডারিংয়ের শেষে, সমস্ত কিছু ধ্বংস করার একটি সুস্পষ্ট উপায় রয়েছে।
অনেকগুলি পয়েন্টার যখনই কোনও সত্তাকে অন্য অ্যাক্সেসের প্রয়োজন হয়, অ্যারে বা যা কিছু স্ক্যান করতে প্রয়োজন হিসাবে সংজ্ঞায়িত করা হয়; এগুলি হ'ল "সন্ধানী"। 3 ডি দৃশ্যের উদাহরণের জন্য - কোনও বস্তু টেক্সচার ব্যবহার করে তবে তার মালিকানা দেয় না; অন্যান্য বস্তু একই টেক্সচার ব্যবহার করতে পারে। একটি বস্তুর ধ্বংস করে না কোন অঙ্গবিন্যাস ধ্বংস ডাকা।
হ্যাঁ এটি সময়সাপেক্ষ তবে এটিই আমি করি। আমার খুব কমই মেমরি ফুটো বা অন্যান্য সমস্যা আছে। তবে তারপরে আমি উচ্চ-পারফরম্যান্স বৈজ্ঞানিক, ডেটা অর্জন এবং গ্রাফিক্স সফ্টওয়্যারের সীমিত ক্ষেত্রে কাজ করি। আমি প্রায়শই ব্যাংকিং এবং ইকমার্স, ইভেন্ট-চালিত জিইউআই বা হাই নেটওয়ার্কওয়ালা অ্যাসিনক্রোনাস বিশৃঙ্খলার মতো লেনদেন করি না। নতুন ফ্যাঙ্গেল উপায়গুলির সেখানে কোনও সুবিধা থাকতে পারে!
দুর্দান্ত প্রশ্ন!
যদি আপনি সি ++ ব্যবহার করেন এবং আপনি রিয়েল-টাইম সিপিইউ-এবং-মেমরি বাউড অ্যাপ্লিকেশনটি (গেমসের মতো) বিকাশ করছেন তবে আপনার নিজের মেমরি ম্যানেজারটি লিখতে হবে।
আমি মনে করি আপনি আরও ভাল করতে পারেন বিভিন্ন লেখকের কিছু আকর্ষণীয় কাজগুলি মার্জ করা, আমি আপনাকে কিছু ইঙ্গিত দিতে পারি:
স্থির আকারের বরাদ্দকারী নেটে সর্বত্র প্রচুর আলোচনা করা হয়
ছোট অবজেক্ট বরাদ্দ 2001 সালে আলেকজান্দ্রেস্কু তাঁর নিখুঁত বই "আধুনিক সি ++ ডিজাইনে" চালু করেছিলেন
দিমিতর লাজারভ রচিত "হাই পারফরম্যান্স হিপ অ্যালকোলেটর" নামক গেম প্রোগ্রামিং জেম 7 (২০০৮) এর একটি দুর্দান্ত অগ্রগতি (উত্স কোড বিতরণ সহ) পাওয়া যায়
সম্পদের একটি দুর্দান্ত তালিকা এই নিবন্ধে পাওয়া যাবে
নিজেই কোনও অযৌক্তিক বরাদ্দকারী লেখা শুরু করবেন না ... প্রথমে ডকুমেন্ট নিজেকে।
একটি কৌশল যা সি ++ এ মেমরি পরিচালনার সাথে জনপ্রিয় হয়ে উঠেছে তা হ'ল RAII । মূলত আপনি রিসোর্স বরাদ্দ পরিচালনা করতে কনস্ট্রাক্টর / ডেস্ট্রাক্টর ব্যবহার করেন। অবশ্যই ব্যতিক্রমী সুরক্ষার কারণে সি ++ তে আরও কিছু অযৌক্তিক বিবরণ রয়েছে তবে প্রাথমিক ধারণাটি বেশ সহজ।
সমস্যাটি সাধারণত মালিকানার একটিতে নেমে আসে। আমি স্কট মায়ার্স দ্বারা কার্যকর সি ++ সিরিজ এবং আন্দ্রেই আলেকজান্দ্রেস্কু দ্বারা আধুনিক সি ++ ডিজাইনটি পড়ার সর্বাধিক পরামর্শ দিচ্ছি।
কীভাবে ফাঁস করবেন না সে সম্পর্কে ইতিমধ্যে অনেক কিছু রয়েছে, তবে ফাঁসগুলি ট্র্যাক করতে আপনাকে যদি কোনও সরঞ্জামের প্রয়োজন হয় তবে একবার দেখুন:
আপনার প্রকল্প জুড়ে মেমরির মালিকানার বিধিগুলি ভাগ করুন এবং জানুন। সিওএম বিধিগুলি ব্যবহার করে সর্বোত্তম ধারাবাহিকতা তৈরি হয় ([প্যারামিটারগুলি কলারের মালিকানাধীন, কলিকে অবশ্যই অনুলিপি করতে হবে; [আউট] প্যারামগুলি কলারের মালিকানাধীন, রেফারেন্স রাখলে কলিকে অবশ্যই একটি অনুলিপি তৈরি করতে হবে; ইত্যাদি))
আপনার প্রোগ্রামের মেমরি ফাঁসগুলি রানটাইমের সময়ও পরীক্ষা করার জন্য ভালগ্রাইন্ড হ'ল একটি ভাল সরঞ্জাম।
এটি লিনাক্সের বেশিরভাগ স্বাদে (অ্যান্ড্রয়েড সহ) এবং ডারউইনে উপলব্ধ।
আপনি যদি আপনার প্রোগ্রামগুলির জন্য ইউনিট পরীক্ষা লেখার জন্য ব্যবহার করেন তবে আপনার পরীক্ষাগুলিতে সিস্টেমেটিক্যালি চলমান ভালগ্রাইন্ডের অভ্যাস থাকা উচিত। এটি প্রাথমিক পর্যায়ে অনেকগুলি মেমরি ফাঁস সম্ভাব্যভাবে এড়াতে পারে। একটি সম্পূর্ণ সফ্টওয়্যার যা সাধারণ পরীক্ষায় তাদের চিহ্নিত করা সাধারণত সহজ।
অবশ্যই এই পরামর্শটি অন্য কোনও মেমরি চেক সরঞ্জামের জন্য বৈধ থাকবে।
আপনি যদি কোনও কিছুর জন্য স্মার্ট পয়েন্টার / ব্যবহার করতে না পারেন (তবে এটি একটি বিশাল লাল পতাকা হওয়া উচিত) তবে আপনার কোডটি দিয়ে এতে টাইপ করুন:
allocate
if allocation succeeded:
{ //scope)
deallocate()
}
এটি সুস্পষ্ট, তবে সুযোগের কোনও কোড টাইপ করার আগে আপনি এটি টাইপ করে নিন তা নিশ্চিত করুন
এই বাগগুলির একটি ঘন ঘন উত্স হ'ল যখন আপনার কাছে এমন কোনও পদ্ধতি থাকে যা কোনও বিষয়ে কোনও রেফারেন্স বা পয়েন্টার গ্রহণ করে তবে মালিকানা অস্পষ্ট করে দেয়। স্টাইল এবং মন্তব্য সম্মেলনগুলি এটি কম সম্ভাবনা তৈরি করতে পারে।
যে ক্ষেত্রে ফাংশনটি অবজেক্টটির মালিকানা নেয় সেটিকে বিশেষ কেস হিসাবে ধরা হোক। এটি ঘটে এমন সমস্ত পরিস্থিতিতে, শিরোনাম ফাইলটিতে ফাংশনের পাশে একটি মন্তব্য লিখতে ভুলবেন না। আপনার নিশ্চিত করার চেষ্টা করা উচিত যে বেশিরভাগ ক্ষেত্রে কোনও মডিউল বা শ্রেণি যা কোনও বস্তুকে বরাদ্দ দেয় তাও এটির অবনতির জন্য দায়ী।
কনস্ট ব্যবহার করা কিছু ক্ষেত্রে অনেক সাহায্য করতে পারে। যদি কোনও ফাংশন কোনও অবজেক্টকে সংশোধন করে না, এবং এটির কোনও রেফারেন্স সংরক্ষণ করে না যা এটি ফিরে আসার পরে অবিরত থাকে, তবে কনস্টের রেফারেন্সটি গ্রহণ করুন। কলারের কোড পড়া থেকে স্পষ্ট হবে যে আপনার ফাংশনটি অবজেক্টের মালিকানা স্বীকার করে নি। আপনি একই ক্রিয়াকলাপটি একটি অ-কনস্ট্যান্ড পয়েন্টার গ্রহণ করতে পারতেন, এবং কলার কলি মালিকানা স্বীকার করেছেন বা ধরেও নিতে পারেন বা নাও করতে পারেন, তবে দৃ const় রেফারেন্সের সাথে কোনও প্রশ্নই আসে না।
যুক্তি তালিকায় অবিচ্ছিন্ন উল্লেখগুলি ব্যবহার করবেন না। কলার কোডটি পড়ার সময় এটি খুব স্পষ্ট নয় যে কলি প্যারামিটারটির কোনও রেফারেন্স রেখেছিল।
আমি রেফারেন্স গণনা পয়েন্টার সুপারিশ মন্তব্যের সাথে একমত নই। এটি সাধারণত সূক্ষ্মভাবে কাজ করে, তবে যখন আপনার কোনও বাগ থাকে এবং এটি কার্যকর হয় না, বিশেষত যদি আপনার ডেস্ট্রাক্টর অ-তুচ্ছ কিছু করেন, যেমন একটি মাল্টিথ্রেড প্রোগ্রামে। আপনার নকশাটি খুব শক্ত না হলে অবশ্যই রেফারেন্স গণনায়ের প্রয়োজন না হয় তা সংশোধন করার চেষ্টা করুন।
গুরুত্বের নির্দেশাবলী:
টিপ # 1 সর্বদা আপনার ধ্বংসকারীদের "ভার্চুয়াল" ঘোষণা করতে মনে রাখবেন।
টিপ # 2 RAII ব্যবহার করুন
টিপ # 3 বুস্ট এর স্মার্টপয়েন্টার ব্যবহার করুন
- টিপ # 4 আপনার নিজের বগি স্মার্টপয়েন্টারগুলি লিখবেন না, বুস্ট ব্যবহার করুন (একটি প্রকল্পে আমি এখনই বুস্ট ব্যবহার করতে পারি না, এবং আমার নিজের স্মার্ট পয়েন্টারগুলি ডিবাগ করার জন্য ভুগছি, আমি অবশ্যই গ্রহণ করব না) একই রুট আবার, কিন্তু এখন আবার আমি আমাদের নির্ভরতা বৃদ্ধি করতে পারবেন না)
টিপ # 5 যদি এটি কিছু নৈমিত্তিক / অ-পারফরম্যান্স সমালোচনা করে (যেমন হাজার হাজার বস্তু সহ গেমগুলিতে) থর্স্টেন ওটোসেনের বুস্ট পয়েন্টার ধারকটিতে কাজ করে
- টিপ # 6 আপনার পছন্দসই প্ল্যাটফর্মের জন্য যেমন একটি ভিজুয়াল ফাঁস সনাক্তকরণের "ভিএলডি" শিরোনামের জন্য একটি ফাঁস সনাক্তকরণ শিরোনাম সন্ধান করুন
যদি আপনি পারেন তবে বুস্ট শেয়ার্ড_পিটার এবং স্ট্যান্ডার্ড সি ++ অটো_পিটার ব্যবহার করুন। যারা মালিকানা শব্দার্থসত্তা প্রকাশ করে।
আপনি যখন একটি অটো_পিটার ফিরে আসবেন, আপনি কলকারীকে বলছেন যে আপনি তাদের মেমরির মালিকানা দিচ্ছেন।
যখন আপনি একটি শেয়ার্ড_পিটার ফিরে আসেন, আপনি কলকারীকে বলছেন যে আপনার কাছে এটির একটি রেফারেন্স রয়েছে এবং তারা মালিকানার অংশ নেন, তবে এটি কেবল তাদের দায়বদ্ধতা নয়।
এই শব্দার্থবিজ্ঞানগুলি পরামিতিগুলির ক্ষেত্রেও প্রযোজ্য। যদি কলকারী আপনাকে একটি অটো_পিটার পাস করে তবে তারা আপনাকে মালিকানা দিচ্ছে।
অন্যরা প্রথম স্থানে (স্মার্ট পয়েন্টারগুলির মতো) মেমরি ফাঁস এড়ানোর উপায়গুলি উল্লেখ করেছেন। মেমরির সমস্যাগুলি একবার হয়ে গেলে আপনি কেবল একটি প্রোফাইলিং এবং মেমরি-বিশ্লেষণ সরঞ্জাম হ'ল প্রায়শই একমাত্র উপায়।
ভালগ্রাইন্ড মেমচেক একটি দুর্দান্ত ফ্রি।
কেবলমাত্র এমএসভিসির জন্য, প্রতিটি .cpp ফাইলের শীর্ষে নিম্নলিখিতটি যুক্ত করুন:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
তারপরে, ভিএস ২০০৩ বা তার বেশি সংখ্যক ডিবাগ করার সময়, আপনার প্রোগ্রামটি বেরিয়ে যাওয়ার সময় আপনাকে কোনও ফাঁস সম্পর্কে বলা হবে (এটি নতুন / মুছার ট্র্যাক করে)। এটি বেসিক, তবে এটি অতীতে আমাকে সহায়তা করেছে।
ভালগ্রিন্ড (কেবলমাত্র * নিক্স প্ল্যাটফর্মের জন্যই লাভজনক) একটি খুব দুর্দান্ত মেমোরি পরীক্ষক
আপনি যদি নিজের মেমরিটি ম্যানুয়ালি পরিচালনা করতে চলেছেন তবে আপনার দুটি মামলা রয়েছে:
আপনার যদি এই কোনও নিয়ম ভাঙার দরকার হয় তবে দয়া করে এটি নথি করুন।
এটি পয়েন্টারের মালিকানা সম্পর্কে।
আপনি মেমোরি বরাদ্দকরণের ক্রিয়াকলাপগুলি আটকে রাখতে পারেন এবং প্রোগ্রামটি প্রস্থান করার পরে কিছু মেমরি অঞ্চল মুক্ত করা হয়নি কিনা তা দেখতে পারেন (যদিও এটি সমস্ত অ্যাপ্লিকেশনগুলির জন্য উপযুক্ত নয় )।
অপারেটরদের নতুন এবং মুছে ফেলা এবং অন্যান্য মেমরি বরাদ্দকরণের কার্যগুলি প্রতিস্থাপনের মাধ্যমে এটি সংকলন সময়েও করা যেতে পারে।
উদাহরণস্বরূপ এই সাইটে দেখুন [সি ++ তে মেমরি বরাদ্দ ডিবাগিং] নোট: অপারেটর মোছার কৌশলও এই জাতীয় কিছু:
#define DEBUG_DELETE PrepareDelete(__LINE__,__FILE__); delete
#define delete DEBUG_DELETE
আপনি কিছু ভেরিয়েবলে ফাইলটির নাম সংরক্ষণ করতে পারেন এবং যখন ওভারলোডেড মোছার অপারেটরটি জানতে পারে যে এটি যে জায়গা থেকে ডাকা হয়েছিল was এইভাবে আপনার প্রোগ্রাম থেকে প্রতিটি মুছে ফেলা এবং ম্যালোকের সন্ধান পাওয়া যাবে। মেমোরি চেকিংয়ের ক্রম শেষে আপনি মেমরির বরাদ্দকৃত ব্লকটি ফাইল নাম এবং লাইন নম্বর দ্বারা এটি সনাক্তকরণ 'মুছে ফেলা হয়নি' তা জানাতে সক্ষম হবেন যা আপনি কী চান তা অনুমান করি।
আপনি ভিজ্যুয়াল স্টুডিওর আওতায় বাউন্ডস চেকারের মতো কিছু চেষ্টা করতে পারেন যা বেশ আকর্ষণীয় এবং সহজেই ব্যবহারযোগ্য।
আমরা আমাদের সমস্ত বরাদ্দ ফাংশন একটি স্তর দিয়ে আবৃত করি যা সামনে একটি সংক্ষিপ্ত স্ট্রিং এবং শেষে একটি সেন্ডিনেল পতাকা যুক্ত করে। সুতরাং উদাহরণস্বরূপ আপনার "মায়ালোক (pszSomeString, iSize, iAlignment); বা নতুন (" বিবরণ ", iSize) মাইওবজেক্ট (); যা অভ্যন্তরীণভাবে আপনার শিরোনাম এবং সেন্ডিনেলের জন্য নির্দিষ্ট আকারের অতিরিক্ত স্থান বরাদ্দ করে d , নন-ডিবাগ বিল্ডগুলির জন্য এটি মন্তব্য করতে ভুলবেন না! এটি করতে আরও কিছুটা স্মৃতি লাগে তবে সুবিধাগুলি ব্যয় ছাড়িয়ে যায়।
এর তিনটি সুবিধা রয়েছে - প্রথমটি আপনাকে নির্দিষ্ট 'জোন'গুলিতে বরাদ্দকৃত কোডের জন্য দ্রুত অনুসন্ধান করে সহজেই এবং দ্রুত কী কোড ফাঁস হচ্ছে তা ট্র্যাক করার অনুমতি দেয় কিন্তু যখন সেই অঞ্চলগুলি মুক্ত করা উচিত তখন পরিষ্কার হয় না। সমস্ত সেন্ডিনেল অক্ষত আছে তা নিশ্চিত করে পরীক্ষা করে কোনও সীমানা ওভাররাইট করা হয়েছে কিনা তা সনাক্ত করাও কার্যকর হতে পারে। এই গোপনীয় ক্র্যাশগুলি বা অ্যারে মিসপেটগুলি সন্ধান করার সময় এটি আমাদের বহুবার সাশ্রয় করেছে। তৃতীয় সুবিধাটি হ'ল বড় খেলোয়াড়রা কারা তা দেখার জন্য মেমোরির ব্যবহার সন্ধান করা - একটি মেমডাম্পে নির্দিষ্ট বর্ণনার একটি কোলেশন আপনাকে বলে যে 'শব্দ' কখন আপনার প্রত্যাশার চেয়ে আরও বেশি জায়গা নেয়, উদাহরণস্বরূপ।
সি ++ মাথায় রেখে তৈরি করা হয়েছে RAII। আমার মনে হয় সি ++ তে মেমরি পরিচালনা করার পক্ষে এর চেয়ে ভাল আর কোনও উপায় নেই। তবে স্থানীয় সুযোগে খুব বড় অংশ (বাফার অবজেক্টের মতো) বরাদ্দ না করার বিষয়ে সতর্ক থাকুন। এটি স্ট্যাকের ওভারফ্লোগুলি সৃষ্টি করতে পারে এবং যদি এই অংশটি ব্যবহার করার সময় যদি কোনও সীমানা পরীক্ষা করার ক্ষেত্রে কোনও ত্রুটি থাকে তবে আপনি অন্যান্য ভেরিয়েবলগুলি বা ফেরত ঠিকানাগুলি ওভাররাইট করতে পারেন যা সমস্ত ধরণের সুরক্ষা গর্তগুলিতে বাড়ে।
বিভিন্ন জায়গায় বরাদ্দ এবং ধ্বংস সম্পর্কে একমাত্র উদাহরণ থ্রেড তৈরি (আপনার প্যারামিটারটি পাস)। তবে এই ক্ষেত্রে সহজ। থ্রেড তৈরি করার ফাংশন / পদ্ধতিটি এখানে:
struct myparams {
int x;
std::vector<double> z;
}
std::auto_ptr<myparams> param(new myparams(x, ...));
// Release the ownership in case thread creation is successfull
if (0 == pthread_create(&th, NULL, th_func, param.get()) param.release();
...
এখানে পরিবর্তে থ্রেড ফাংশন
extern "C" void* th_func(void* p) {
try {
std::auto_ptr<myparams> param((myparams*)p);
...
} catch(...) {
}
return 0;
}
খুব সহজ না? থ্রেড তৈরির ক্ষেত্রে ব্যর্থ হওয়ার পরে অটো_পিটার দ্বারা সংস্থানটি নিখরচায় (মুছে ফেলা) হয়ে যাবে, অন্যথায় মালিকানা থ্রেডে চলে যাবে। থ্রেড যদি এত দ্রুত হয় যে তৈরি হওয়ার পরে এটি উত্সটির আগে প্রকাশ করে
param.release();
মূল ফাংশন / পদ্ধতিতে ডাকা হয়? কোনো কিছুই নেই! কারণ আমরা অটো_পিটারকে অবনতি করতে 'বলব'। সি ++ মেমরি পরিচালনা কি সহজ না? চিয়ার্স,
এমা!
আপনি অন্যান্য সংস্থাগুলি (হ্যান্ডলগুলি, ফাইলগুলি, ডিবি সংযোগগুলি, সকেটগুলি ...) পরিচালনা করুন ঠিক তেমনভাবে মেমরি পরিচালনা করুন। জিসি তাদের সাথে আপনাকে সহায়তা করবে না।
ঠিক কোন ফাংশন থেকে এক রিটার্ন। এইভাবে আপনি সেখানে deallocation করতে পারেন এবং এটি কখনও মিস করবেন না।
অন্যথায় ভুল করা খুব সহজ:
new a()
if (Bad()) {delete a; return;}
new b()
if (Bad()) {delete a; delete b; return;}
... // etc.