সি ++ এ মেমরি ফাঁস এড়াতে সাধারণ নির্দেশিকা [বন্ধ]


130

আমি সি ++ প্রোগ্রামগুলিতে মেমরি ফাঁস করি না তা নিশ্চিত করার জন্য কয়েকটি সাধারণ টিপস কী? গতিশীলরূপে বরাদ্দ করা হয়েছে এমন কাকে মুক্ত করতে হবে তা আমি কীভাবে আবিষ্কার করব?


26
আমার কাছে বেশ গঠনমূলক বলে মনে হচ্ছে।
শোয়েব

11
এটি গঠনমূলক। এবং উত্তরগুলি তথ্য, দক্ষতা, রেফারেন্স ইত্যাদির দ্বারা সমর্থিত এবং উর্ধ্বতন / উত্তরগুলির সংখ্যা দেখুন .. !!
সম্মিতা চথুরঙ্গ

উত্তর:


40

ম্যানুয়ালি ম্যানুয়ালি পরিচালনা করার পরিবর্তে, প্রযোজ্য যেখানে স্মার্ট পয়েন্টার ব্যবহার করার চেষ্টা করুন।
কটাক্ষপাত বুস্ট liberal এর সংক্ষিপ্ত রূপ , TR1 , এবং স্মার্ট পয়েন্টার
এছাড়াও স্মার্ট পয়েন্টারগুলি এখন সি ++ স্ট্যান্ডার্ডের সি ++ 11 নামক একটি অংশ ।


1
জি ++ ব্যবহার করে সংকলন করতে একজনকে পরম যোগ করতে হবে: -std = c ++ 0x
Paweł Szczur

অথবা আপনি জি ++ দিয়ে ফ্ল্যাগ মান -std = সি ++ 11 ব্যবহার করে সংকলন করতে পারেন
প্রভাস রাঠোর

200

আমি আরআইআই এবং স্মার্ট পয়েন্টার সম্পর্কিত সমস্ত পরামর্শের পুরোপুরি সমর্থন করি, তবে আমি কিছুটা উচ্চ-স্তরের টিপও যুক্ত করতে চাই: পরিচালনা করার পক্ষে সবচেয়ে সহজ মেমরিটি আপনি কখনই বরাদ্দ করেননি memory সি # এবং জাভা এর মতো ভাষার মতো নয়, যেখানে বেশ কিছু সবকিছুই একটি রেফারেন্স, সি ++ এ আপনি যখনই পারেন ততক্ষণ স্ট্যাকগুলিতে রাখা উচিত। যেহেতু আমি বেশিরভাগ লোককে (ডাঃ স্ট্রাস্ট্রাপ সহ) দেখিয়েছি, আবর্জনা সংগ্রহ সি ++ এ কখনও জনপ্রিয় না হওয়ার মূল কারণ হ'ল সু-লিখিত সি ++ প্রথম স্থানটিতে খুব বেশি আবর্জনা তৈরি করে না।

লিখবেন না

Object* x = new Object;

অথবা এমনকি

shared_ptr<Object> x(new Object);

আপনি যখন লিখতে পারেন

Object x;

34
আমি আশা করি আমি এটি একটি +10 দিতে পারতাম। এটি আজ আমি বেশিরভাগ সি ++ প্রোগ্রামারদের সাথে দেখা সবচেয়ে বড় সমস্যা এবং আমি ধরে নিই কারণ তারা সি ++ এর আগে জাভা শিখেছিল।
ক্রিস্টোফার জনসন

অত্যন্ত আকর্ষণীয় বিষয় - আমি ভাবছিলাম যে কেন অন্যান্য ভাষার তুলনায় আমার কাছে সি ++ মেমরি পরিচালনার সমস্যাগুলি খুব কম হয় তবে এখন আমি কেন তা দেখি: এটি আসলে ভ্যানিলা সি এর মতো
স্ট্যাকগুলিতে স্টাফকে

আপনি অবজেক্ট এক্স লিখলে আপনি কি করবেন; এবং তারপর এক্স দূরে নিক্ষেপ করতে চান? বলুন x মূল পদ্ধতিতে তৈরি হয়েছিল।
ইয়ামচা

3
@ ব্যবহারকারী 1316459 সি ++ আপনাকে ফ্লাইতে স্কোপগুলি তৈরি করতে দেয়। আপনাকে যা করতে হবে তা হ'ল এক্স এর জীবনকালকে এভাবে ব্রেসগুলির মধ্যে মোড়ানো হয়: rap অবজেক্ট এক্স; x.DoSomething; }। চূড়ান্ত '}' এর পরে, এক্স এর ডেস্ট্রাক্টরকে এতে থাকা যে কোনও সংস্থান থেকে মুক্ত করতে ডাকা হবে। যদি এক্স, নিজেই, মেমরিটি গাদাতে বরাদ্দ করা হয় তবে আমি এটিকে একটি অনন্য_প্টারে মোড়ানোর পরামর্শ দিচ্ছি যাতে এটি সহজে এবং যথাযথভাবে পরিষ্কার হয়।
ডেভিড পিটারসন

1
রবার্ট: হ্যাঁ রস "নতুন [কোডযুক্ত কোড] কখনই লিখবেন না" বলেছিলেন না, তিনি বলেছিলেন যে " যখন আপনি কেবল [স্ট্যাকের উপর চাপিয়ে দিতে পারেন]" লিখবেন না [এটি ] "। বেশিরভাগ পরিস্থিতিতেই বিশেষত কর্মক্ষমতা-নিবিড় কোডের জন্য গাদা বড় আকারের জিনিসগুলি সঠিক কল হতে থাকবে।
কোডেটাকু

104

RAII ব্যবহার করুন

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

এই পোস্টটি পুনরাবৃত্তি বলে মনে হচ্ছে, তবে সি ++ এ, জানা সবচেয়ে প্রাথমিক প্যাটার্নটি হল 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) সম্পর্কে যত্ন নেওয়ার দরকার নেই ...

সম্পাদনা (2012-02-12)

"স্কোপড অবজেক্টস ... ধ্বংস হবে ... প্রস্থানটি কোনও ব্যাপার নয়" এটি সম্পূর্ণ সত্য নয়। RAII কে প্রতারণা করার উপায় রয়েছে। সমাপ্তির কোনও স্বাদ () ক্লিনআপকে বাইপাস করবে। প্রস্থান (EXIT_SUCCESS) এই ক্ষেত্রে একটি অক্সিমারন।

- উইলহেমটেল

উইলহেমটেল এ সম্পর্কে বেশ সঠিক: রাইআইআই কে প্রতারণা করার ব্যতিক্রমী উপায় রয়েছে, যা প্রক্রিয়াটি হঠাৎ করে থামিয়ে দেয় leading

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

তবে আমাদের অবশ্যই এখনও এই মামলাগুলি সম্পর্কে জানতে হবে কারণ এগুলি খুব কমই ঘটেছিল, তবুও তারা ঘটতে পারে।

(কে ফোন করেছেন terminateবা exitনৈমিত্তিক সি ++ কোডে? ... আমার মনে আছে জিএলইউটি দিয়ে খেলতে গিয়ে এই সমস্যার সাথে মোকাবিলা করতে হয়েছিল : এই লাইব্রেরিটি সি সি ++ বিকাশকারীদের পক্ষে যত্নশীল না করার মতো বিষয়টিকে সক্রিয়ভাবে নকশাকৃত করে গড়ে তোলা হয়েছে design সম্পর্কে স্ট্যাক বরাদ্দ তথ্য , বা সম্পর্কে "আকর্ষণীয়" সিদ্ধান্ত থাকার কখনো তাদের প্রধান লুপ থেকে ফিরে ... আমি যে বিষয়ে মন্তব্য না)


ডেরাইআইএসট্যাটিক () মেমরি ফাঁস করে না তা নিশ্চিত হওয়ার জন্য কি টি শ্রেণি আরএআইআই ব্যবহার করবে না? যেমন টি পি (); p.doSandwich (); যদিও আমি আসলে এ সম্পর্কে খুব বেশি জানি না।
ড্যানিয়েল ও

@ অগ্রে গীতসংহিতা 33: মন্তব্যের জন্য ধন্যবাদ। অবশ্যই, আপনি ঠিক বলেছেন। আমি উভয় লিঙ্কগুলিকে আরএআইআই উইকিপিডিয়া পৃষ্ঠায় যুক্ত করেছি এবং আরএআইআই কিসের একটি ছোট সংক্ষিপ্তসার।
প্যারাসেবল

1
@ শিফিটবিট: তিনটি উপায়, পছন্দ অনুসারে: _ _ _ 1. এসটিএল ধারকটির ভিতরে আসল বস্তুটি রাখুন। _ _ _ ২. এসটিএল ধারকটির অভ্যন্তরে অবজেক্টগুলির স্মার্ট পয়েন্টার (শেয়ারড_পিটার) রাখুন। _ _ _ ৩. এসটিএল ধারকটির ভিতরে কাঁচা পয়েন্টার রাখুন, তবে ডেটাতে কোনও অ্যাক্সেস নিয়ন্ত্রণের জন্য ধারকটি মোড়ানো। মোড়ক নিশ্চিত করবে যে ডেস্ট্রাক্টর বরাদ্দকৃত অবজেক্টগুলি মুক্ত করবে এবং পাত্রে অ্যাক্সেস / সংশোধন করার সময় মোড়ক অ্যাক্সেসররা নিশ্চিত করবে যে কিছুই ভেঙে নেই।
প্যারেসাল

1
@ রবার্ট: সি ++ তে, আপনি কোনও ফাংশনে doRAIIDynamic ব্যবহার করবেন যা অবশ্যই বাচ্চা বা পিতামাতার ফাংশন (বা বৈশ্বিক সুযোগ) এর মালিকানা দিতে হবে। বা যখন আপনি কোনও কারখানার মাধ্যমে কোনও পলিমার্ফ অবজেক্টে কোনও ইন্টারফেস পান (স্মার্ট পয়েন্টারটি সঠিকভাবে লেখা থাকে তবে তা ফেরত দেওয়া)। সি ++ ১১-তে,
এটির

2
@ রবার্ট: ... নোট করুন যে স্ট্যাকের উপর কোনও বস্তু ঘোষণার অর্থ এই নয় যে অবজেক্টটি অভ্যন্তরীণভাবে গাদা ব্যবহার করে না (ডাবল প্রত্যাখ্যান নোট করুন ... :-) ...)। উদাহরণস্বরূপ, ছোট স্ট্রিং অপ্টিমাইজেশানের সাথে প্রয়োগ করা std :: স্ট্রিংয়ের ছোট স্ট্রিং (~ 15 অক্ষর) এর জন্য "ক্লাসের স্ট্যাকের উপর" একটি বাফার থাকবে এবং বৃহত্তর স্ট্রিংয়ের জন্য স্তূপের একটি স্মৃতিতে একটি পয়েন্টার ব্যবহার করবে ... তবে বাইরে থেকে, স্টাড :: স্ট্রিংটি এখনও একটি মান ধরণের যা আপনি স্ট্যাকের (সাধারণত) হিসাবে ঘোষণা করেন এবং আপনি কোনও পূর্ণসংখ্যার ব্যবহার হিসাবে এটি ব্যবহার করেন (যেমন: আপনি পলিমার্ফ শ্রেণীর জন্য কোনও ইন্টারফেস ব্যবহার করবেন) use
পেরেসারবাল

25

আপনি বুস্টের স্মার্ট পয়েন্টারগুলির মতো স্মার্ট পয়েন্টারগুলি দেখতে চাইবেন ।

পরিবর্তে

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!
}

বরাবরের মতো, আপনার চিন্তাভাবনা ক্যাপটি কোনও সরঞ্জাম দিয়ে ব্যবহার করুন ...



11

বেশিরভাগ স্মৃতি ফাঁস হ'ল অবজেক্টের মালিকানা এবং আজীবন সম্পর্কে পরিষ্কার না হওয়ার ফলাফল are

প্রথম কাজটি হ'ল স্ট্যাকের উপর বরাদ্দ করা যখনই আপনি পারেন। এটি বেশিরভাগ ক্ষেত্রেই আপনাকে মোকাবেলা করে যেখানে কোনও উদ্দেশ্যে কোনও একক বস্তু বরাদ্দ করতে হবে।

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

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

এসটিএল সহ আমার বিফটি হ'ল এটি ভ্যালু অবজেক্টগুলির উপর এত বেশি কেন্দ্রীভূত হয় যখন বেশিরভাগ অ্যাপ্লিকেশনে অবজেক্টগুলি অনন্য সত্তা থাকে যেখানে সেই ধারকগুলিতে ব্যবহারের জন্য অর্থপূর্ণ অনুলিপি শব্দার্থবিজ্ঞান থাকে না।


10

বাহ, আপনি বাচ্চাদের বাচ্চাদের এবং আপনার নতুন-জঞ্জাল আবর্জনা সংগ্রহকারী ...

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

create a thing
use that thing
destroy that thing

কখনও কখনও এটি বিভিন্ন জায়গায় বিভিন্ন জায়গায় তৈরি করা এবং ধ্বংস করা প্রয়োজন; আমি এড়াতে কঠিন মনে করি।

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

অনেকগুলি পয়েন্টার যখনই কোনও সত্তাকে অন্য অ্যাক্সেসের প্রয়োজন হয়, অ্যারে বা যা কিছু স্ক্যান করতে প্রয়োজন হিসাবে সংজ্ঞায়িত করা হয়; এগুলি হ'ল "সন্ধানী"। 3 ডি দৃশ্যের উদাহরণের জন্য - কোনও বস্তু টেক্সচার ব্যবহার করে তবে তার মালিকানা দেয় না; অন্যান্য বস্তু একই টেক্সচার ব্যবহার করতে পারে। একটি বস্তুর ধ্বংস করে না কোন অঙ্গবিন্যাস ধ্বংস ডাকা।

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


আমি পুরোপুরি একমত। এম্বেড থাকা পরিবেশে কাজ করা আপনার তৃতীয় পক্ষের লাইব্রেরির বিলাসিতা নাও থাকতে পারে।
সাইমন

6
আমি একমত নই "সেই জিনিসটি ব্যবহার করুন" এর অংশে, যদি কোনও প্রত্যাবর্তন বা কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয়, তবে আপনি deallocation মিস করবেন। পারফরম্যান্সের ক্ষেত্রে, std :: auto_ptr এর জন্য আপনার কোনও মূল্য হবে না। এমন নয় যে আমি কখনই আপনার মতো কোড করি না। এটি কেবলমাত্র 100% এবং 99% সুরক্ষিত কোডের মধ্যে পার্থক্য রয়েছে। :-)
প্যারাসেবল

8

দুর্দান্ত প্রশ্ন!

যদি আপনি সি ++ ব্যবহার করেন এবং আপনি রিয়েল-টাইম সিপিইউ-এবং-মেমরি বাউড অ্যাপ্লিকেশনটি (গেমসের মতো) বিকাশ করছেন তবে আপনার নিজের মেমরি ম্যানেজারটি লিখতে হবে।

আমি মনে করি আপনি আরও ভাল করতে পারেন বিভিন্ন লেখকের কিছু আকর্ষণীয় কাজগুলি মার্জ করা, আমি আপনাকে কিছু ইঙ্গিত দিতে পারি:

  • স্থির আকারের বরাদ্দকারী নেটে সর্বত্র প্রচুর আলোচনা করা হয়

  • ছোট অবজেক্ট বরাদ্দ 2001 সালে আলেকজান্দ্রেস্কু তাঁর নিখুঁত বই "আধুনিক সি ++ ডিজাইনে" চালু করেছিলেন

  • দিমিতর লাজারভ রচিত "হাই পারফরম্যান্স হিপ অ্যালকোলেটর" নামক গেম প্রোগ্রামিং জেম 7 (২০০৮) এর একটি দুর্দান্ত অগ্রগতি (উত্স কোড বিতরণ সহ) পাওয়া যায়

  • সম্পদের একটি দুর্দান্ত তালিকা এই নিবন্ধে পাওয়া যাবে

নিজেই কোনও অযৌক্তিক বরাদ্দকারী লেখা শুরু করবেন না ... প্রথমে ডকুমেন্ট নিজেকে।


5

একটি কৌশল যা সি ++ এ মেমরি পরিচালনার সাথে জনপ্রিয় হয়ে উঠেছে তা হ'ল RAII । মূলত আপনি রিসোর্স বরাদ্দ পরিচালনা করতে কনস্ট্রাক্টর / ডেস্ট্রাক্টর ব্যবহার করেন। অবশ্যই ব্যতিক্রমী সুরক্ষার কারণে সি ++ তে আরও কিছু অযৌক্তিক বিবরণ রয়েছে তবে প্রাথমিক ধারণাটি বেশ সহজ।

সমস্যাটি সাধারণত মালিকানার একটিতে নেমে আসে। আমি স্কট মায়ার্স দ্বারা কার্যকর সি ++ সিরিজ এবং আন্দ্রেই আলেকজান্দ্রেস্কু দ্বারা আধুনিক সি ++ ডিজাইনটি পড়ার সর্বাধিক পরামর্শ দিচ্ছি।


5

কীভাবে ফাঁস করবেন না সে সম্পর্কে ইতিমধ্যে অনেক কিছু রয়েছে, তবে ফাঁসগুলি ট্র্যাক করতে আপনাকে যদি কোনও সরঞ্জামের প্রয়োজন হয় তবে একবার দেখুন:


বাউন্ডসেকার 404ing।
ট্যাঙ্কোরস্যামশ

4

ইউজার স্মার্ট পয়েন্টার আপনি যেখানেই পারেন! পুরো ক্লাসের মেমরি ফুটো কেবল চলে যায়।


4

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


4

আপনার প্রোগ্রামের মেমরি ফাঁসগুলি রানটাইমের সময়ও পরীক্ষা করার জন্য ভালগ্রাইন্ড হ'ল একটি ভাল সরঞ্জাম।

এটি লিনাক্সের বেশিরভাগ স্বাদে (অ্যান্ড্রয়েড সহ) এবং ডারউইনে উপলব্ধ।

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

অবশ্যই এই পরামর্শটি অন্য কোনও মেমরি চেক সরঞ্জামের জন্য বৈধ থাকবে।


3

এছাড়াও, স্টাডি লাইব্রেরি ক্লাস (যেমন ভেক্টর) থাকলে ম্যানুয়ালি বরাদ্দ মেমরি ব্যবহার করবেন না। আপনি যদি সেই নিয়ম লঙ্ঘন করেন তবে নিশ্চিত হন যে আপনার ভার্চুয়াল ডেস্ট্রাক্টর রয়েছে।


2

আপনি যদি কোনও কিছুর জন্য স্মার্ট পয়েন্টার / ব্যবহার করতে না পারেন (তবে এটি একটি বিশাল লাল পতাকা হওয়া উচিত) তবে আপনার কোডটি দিয়ে এতে টাইপ করুন:

allocate
if allocation succeeded:
{ //scope)
     deallocate()
}

এটি সুস্পষ্ট, তবে সুযোগের কোনও কোড টাইপ করার আগে আপনি এটি টাইপ করে নিন তা নিশ্চিত করুন


2

এই বাগগুলির একটি ঘন ঘন উত্স হ'ল যখন আপনার কাছে এমন কোনও পদ্ধতি থাকে যা কোনও বিষয়ে কোনও রেফারেন্স বা পয়েন্টার গ্রহণ করে তবে মালিকানা অস্পষ্ট করে দেয়। স্টাইল এবং মন্তব্য সম্মেলনগুলি এটি কম সম্ভাবনা তৈরি করতে পারে।

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

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

যুক্তি তালিকায় অবিচ্ছিন্ন উল্লেখগুলি ব্যবহার করবেন না। কলার কোডটি পড়ার সময় এটি খুব স্পষ্ট নয় যে কলি প্যারামিটারটির কোনও রেফারেন্স রেখেছিল।

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


2

গুরুত্বের নির্দেশাবলী:

টিপ # 1 সর্বদা আপনার ধ্বংসকারীদের "ভার্চুয়াল" ঘোষণা করতে মনে রাখবেন।

টিপ # 2 RAII ব্যবহার করুন

টিপ # 3 বুস্ট এর স্মার্টপয়েন্টার ব্যবহার করুন

- টিপ # 4 আপনার নিজের বগি স্মার্টপয়েন্টারগুলি লিখবেন না, বুস্ট ব্যবহার করুন (একটি প্রকল্পে আমি এখনই বুস্ট ব্যবহার করতে পারি না, এবং আমার নিজের স্মার্ট পয়েন্টারগুলি ডিবাগ করার জন্য ভুগছি, আমি অবশ্যই গ্রহণ করব না) একই রুট আবার, কিন্তু এখন আবার আমি আমাদের নির্ভরতা বৃদ্ধি করতে পারবেন না)

টিপ # 5 যদি এটি কিছু নৈমিত্তিক / অ-পারফরম্যান্স সমালোচনা করে (যেমন হাজার হাজার বস্তু সহ গেমগুলিতে) থর্স্টেন ওটোসেনের বুস্ট পয়েন্টার ধারকটিতে কাজ করে

- টিপ # 6 আপনার পছন্দসই প্ল্যাটফর্মের জন্য যেমন একটি ভিজুয়াল ফাঁস সনাক্তকরণের "ভিএলডি" শিরোনামের জন্য একটি ফাঁস সনাক্তকরণ শিরোনাম সন্ধান করুন


আমি একটি কৌশল মিস করছি, তবে কীভাবে 'গেম' এবং 'অ-অভিনয়-সমালোচনা' একই বাক্যে থাকতে পারে?
অ্যাডাম নায়লার

গেমস অবশ্যই সমালোচনামূলক দৃশ্যের একটি উদাহরণ। সেখানে পরিষ্কার হতে পারে ব্যর্থ হয়েছে
রবার্ট গল্ড

ক্লাসে কমপক্ষে একটি ভার্চুয়াল পদ্ধতি থাকলে টিপ # 1 টি প্রয়োগ করা উচিত। আমি কোনও ক্লাসে কখনই বেহুদা ভার্চুয়াল ডেস্ট্রাক্টর চাপিয়ে দেব না যা বহুবর্ষগত উত্তরাধিকার গাছের বেস ক্লাস হিসাবে পরিবেশন করা নয়।
এন্ট্রিড

1

যদি আপনি পারেন তবে বুস্ট শেয়ার্ড_পিটার এবং স্ট্যান্ডার্ড সি ++ অটো_পিটার ব্যবহার করুন। যারা মালিকানা শব্দার্থসত্তা প্রকাশ করে।

আপনি যখন একটি অটো_পিটার ফিরে আসবেন, আপনি কলকারীকে বলছেন যে আপনি তাদের মেমরির মালিকানা দিচ্ছেন।

যখন আপনি একটি শেয়ার্ড_পিটার ফিরে আসেন, আপনি কলকারীকে বলছেন যে আপনার কাছে এটির একটি রেফারেন্স রয়েছে এবং তারা মালিকানার অংশ নেন, তবে এটি কেবল তাদের দায়বদ্ধতা নয়।

এই শব্দার্থবিজ্ঞানগুলি পরামিতিগুলির ক্ষেত্রেও প্রযোজ্য। যদি কলকারী আপনাকে একটি অটো_পিটার পাস করে তবে তারা আপনাকে মালিকানা দিচ্ছে।


1

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

ভালগ্রাইন্ড মেমচেক একটি দুর্দান্ত ফ্রি।


1

কেবলমাত্র এমএসভিসির জন্য, প্রতিটি .cpp ফাইলের শীর্ষে নিম্নলিখিতটি যুক্ত করুন:

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

তারপরে, ভিএস ২০০৩ বা তার বেশি সংখ্যক ডিবাগ করার সময়, আপনার প্রোগ্রামটি বেরিয়ে যাওয়ার সময় আপনাকে কোনও ফাঁস সম্পর্কে বলা হবে (এটি নতুন / মুছার ট্র্যাক করে)। এটি বেসিক, তবে এটি অতীতে আমাকে সহায়তা করেছে।


1

ভালগ্রিন্ড (কেবলমাত্র * নিক্স প্ল্যাটফর্মের জন্যই লাভজনক) একটি খুব দুর্দান্ত মেমোরি পরীক্ষক


1

আপনি যদি নিজের মেমরিটি ম্যানুয়ালি পরিচালনা করতে চলেছেন তবে আপনার দুটি মামলা রয়েছে:

  1. আমি অবজেক্টটি তৈরি করেছি (সম্ভবত পরোক্ষভাবে, একটি নতুন ফাংশনকে বরাদ্দকারী কোনও ফাংশন কল করে), আমি এটি ব্যবহার করি (বা কোনও ফাংশন যা আমি কল করি এটি ব্যবহার করে), তারপরে আমি এটিকে মুক্ত করি।
  2. কেউ আমাকে রেফারেন্স দিয়েছে, সুতরাং আমার এটিকে মুক্ত করা উচিত নয়।

আপনার যদি এই কোনও নিয়ম ভাঙার দরকার হয় তবে দয়া করে এটি নথি করুন।

এটি পয়েন্টারের মালিকানা সম্পর্কে।


1
  • গতিশীল অবজেক্টগুলি বরাদ্দ এড়াতে চেষ্টা করুন। যতক্ষণ ক্লাসে উপযুক্ত কনস্ট্রাক্টর এবং ডেস্ট্রাক্টর থাকে, ক্লাস টাইপের একটি ভেরিয়েবল ব্যবহার করুন, এটির নির্দেশক নয়, এবং আপনি গতিশীল বরাদ্দ এবং অবনতি এড়ান কারণ সংকলকটি এটি আপনার জন্য করবে।
    আসলে এটি হ'ল "স্মার্ট পয়েন্টার" দ্বারা ব্যবহৃত মেকানিজম এবং অন্যান্য লেখকরা RAII হিসাবে উল্লেখ করেছেন ;-)।
  • আপনি যখন অন্য ফাংশনে অবজেক্টগুলি পাস করেন তখন পয়েন্টারগুলির তুলনায় রেফারেন্স পরামিতিগুলি পছন্দ করুন। এটি কিছু সম্ভাব্য ত্রুটি এড়ায়।
  • প্যারামিটার কনস্টের ঘোষণা, যেখানে সম্ভব, বিশেষত বস্তুগুলিতে পয়েন্টার। এইভাবে অবজেক্টগুলিকে "আকস্মিকভাবে" মুক্তি দেওয়া যায় না (যদি আপনি কন্সট দূরে ফেলে থাকেন তবে ;-))।
  • আপনি যে প্রোগ্রামটিতে মেমরি বরাদ্দ এবং অবনমন করেন সেখানে প্রোগ্রামের জায়গাগুলির সংখ্যা হ্রাস করুন। E. g। আপনি যদি একই ধরণের কয়েকবার বরাদ্দ করেন বা বিনামূল্যে করেন তবে এর জন্য একটি ফাংশন লিখুন (বা একটি ফ্যাক্টরি পদ্ধতি ;-))।
    এইভাবে আপনি প্রয়োজনবোধে সহজেই ডিবাগ আউটপুট (যা ঠিকানাগুলি বরাদ্দ করা হয় এবং নির্বিঘ্নিত হয় ...) তৈরি করতে পারেন।
  • একটি একক ফাংশন থেকে বেশ কয়েকটি সম্পর্কিত শ্রেণীর অবজেক্টগুলিকে বরাদ্দ করতে একটি কারখানা ফাংশন ব্যবহার করুন।
  • যদি আপনার ক্লাসগুলির ভার্চুয়াল ডেস্ট্রাক্টর সহ একটি সাধারণ বেস শ্রেণি থাকে তবে আপনি একই ফাংশন (বা স্থিতিশীল পদ্ধতি) ব্যবহার করে তাদের সকলকে মুক্ত করতে পারেন।
  • শুদ্ধকরণের মতো সরঞ্জামগুলির সাথে আপনার প্রোগ্রামটি পরীক্ষা করুন (দুর্ভাগ্যক্রমে অনেকগুলি $ / € / ...)।

0

আপনি মেমোরি বরাদ্দকরণের ক্রিয়াকলাপগুলি আটকে রাখতে পারেন এবং প্রোগ্রামটি প্রস্থান করার পরে কিছু মেমরি অঞ্চল মুক্ত করা হয়নি কিনা তা দেখতে পারেন (যদিও এটি সমস্ত অ্যাপ্লিকেশনগুলির জন্য উপযুক্ত নয় )।

অপারেটরদের নতুন এবং মুছে ফেলা এবং অন্যান্য মেমরি বরাদ্দকরণের কার্যগুলি প্রতিস্থাপনের মাধ্যমে এটি সংকলন সময়েও করা যেতে পারে।

উদাহরণস্বরূপ এই সাইটে দেখুন [সি ++ তে মেমরি বরাদ্দ ডিবাগিং] নোট: অপারেটর মোছার কৌশলও এই জাতীয় কিছু:

#define DEBUG_DELETE PrepareDelete(__LINE__,__FILE__); delete
#define delete DEBUG_DELETE

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

আপনি ভিজ্যুয়াল স্টুডিওর আওতায় বাউন্ডস চেকারের মতো কিছু চেষ্টা করতে পারেন যা বেশ আকর্ষণীয় এবং সহজেই ব্যবহারযোগ্য।


0

আমরা আমাদের সমস্ত বরাদ্দ ফাংশন একটি স্তর দিয়ে আবৃত করি যা সামনে একটি সংক্ষিপ্ত স্ট্রিং এবং শেষে একটি সেন্ডিনেল পতাকা যুক্ত করে। সুতরাং উদাহরণস্বরূপ আপনার "মায়ালোক (pszSomeString, iSize, iAlignment); বা নতুন (" বিবরণ ", iSize) মাইওবজেক্ট (); যা অভ্যন্তরীণভাবে আপনার শিরোনাম এবং সেন্ডিনেলের জন্য নির্দিষ্ট আকারের অতিরিক্ত স্থান বরাদ্দ করে d , নন-ডিবাগ বিল্ডগুলির জন্য এটি মন্তব্য করতে ভুলবেন না! এটি করতে আরও কিছুটা স্মৃতি লাগে তবে সুবিধাগুলি ব্যয় ছাড়িয়ে যায়।

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


0

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


0

বিভিন্ন জায়গায় বরাদ্দ এবং ধ্বংস সম্পর্কে একমাত্র উদাহরণ থ্রেড তৈরি (আপনার প্যারামিটারটি পাস)। তবে এই ক্ষেত্রে সহজ। থ্রেড তৈরি করার ফাংশন / পদ্ধতিটি এখানে:

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();

মূল ফাংশন / পদ্ধতিতে ডাকা হয়? কোনো কিছুই নেই! কারণ আমরা অটো_পিটারকে অবনতি করতে 'বলব'। সি ++ মেমরি পরিচালনা কি সহজ না? চিয়ার্স,

এমা!


0

আপনি অন্যান্য সংস্থাগুলি (হ্যান্ডলগুলি, ফাইলগুলি, ডিবি সংযোগগুলি, সকেটগুলি ...) পরিচালনা করুন ঠিক তেমনভাবে মেমরি পরিচালনা করুন। জিসি তাদের সাথে আপনাকে সহায়তা করবে না।


-3

ঠিক কোন ফাংশন থেকে এক রিটার্ন। এইভাবে আপনি সেখানে deallocation করতে পারেন এবং এটি কখনও মিস করবেন না।

অন্যথায় ভুল করা খুব সহজ:

new a()
if (Bad()) {delete a; return;}
new b()
if (Bad()) {delete a; delete b; return;}
... // etc.

আপনার উত্তর এখানে উদাহরণ কোডের সাথে মেলে না? আমি উত্তর "শুধুমাত্র একটি রিটার্ন" এর সাথে একমত তবে উদাহরণ কোডটি কী করবে না তা দেখাচ্ছে।
সাইমন

1
সি ++ রাইআইআই এর বক্তব্য হ'ল আপনি যে ধরনের কোড লিখেছেন তা এড়াতে। সি তে, এটি সম্ভবত সঠিক জিনিস। তবে সি ++ এ আপনার কোড ত্রুটিযুক্ত। উদাহরণস্বরূপ: নতুন খ () নিক্ষেপ করলে কী হবে? আপনি ফুটো a।
প্যার্সেবল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.