এটি মুছে ফেলার পরে কোনও পয়েন্টার শুকানো কি ভাল অনুশীলন?


150

আমি এই বলে স্মার্ট পয়েন্টার ব্যবহার করে শুরু করব এবং আপনাকে কখনই এ নিয়ে চিন্তা করতে হবে না।

নিম্নলিখিত কোডে সমস্যাগুলি কী?

Foo * p = new Foo;
// (use p)
delete p;
p = NULL;

এটি একটি উত্তর এবং অন্য প্রশ্নের মন্তব্যে স্পার্ক হয়েছিল । নীল বাটারওয়ার্থের একটি মন্তব্য কয়েকটি উত্স তৈরি করেছে:

মুছে ফেলার পরে NULL তে পয়েন্টার সেট করা সি ++ তে সর্বজনীন ভাল অনুশীলন নয়। এমন সময় আছে যখন এটি করা ভাল কাজ এবং যখন সময় অর্থহীন এবং ত্রুটিগুলি আড়াল করতে পারে।

প্রচুর পরিস্থিতি রয়েছে যেখানে এটি কোনও উপকারে আসেনি। তবে আমার অভিজ্ঞতায় এটি আঘাত করতে পারে না। কেউ আমাকে আলোকিত করেন।


6
@ আন্ড্রে: প্রযুক্তিগতভাবে, এটি অপরিবর্তিত যা হবার সম্ভাবনা রয়েছে তা হ'ল আপনি আগের মতো একই মেমরিটি অ্যাক্সেস করেছেন তবে এটি এখন অন্য কোনও কিছুর দ্বারা ব্যবহৃত হতে পারে। যদি আপনি দু'বার মেমরি মুছে ফেলেন তবে সম্ভবত এটি আপনার প্রোগ্রামের প্রয়োগটি একটি কঠিন-সন্ধানী উপায়ে স্ক্রু করে দেবে। এটি deleteনাল পয়েন্টারের কাছে নিরাপদ , যদিও পয়েন্টার শূন্য করা ভাল কারণ হতে পারে এটি একটি কারণ।
ডেভিড থর্নলি

5
@ আন্দ্রে পেনা, এটি অপরিজ্ঞাত। প্রায়শই এটি পুনরাবৃত্তিযোগ্যও নয়। আপনি ডিবাগ করার সময় ত্রুটিটি আরও দৃশ্যমান করার জন্য এবং সম্ভবত এটি আরও পুনরাবৃত্তযোগ্য করতে পয়েন্টারটি NULL এ সেট করেছেন।
মার্ক র্যানসম

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

16
উড়ন্ত রাক্ষসগুলি একটি বৈশিষ্ট্য, কোনও বাগ নয়।
jball 23

3
এই প্রশ্নটি সদৃশ নয় কারণ অন্য প্রশ্নটি সি সম্পর্কে এবং এটি একটি সি ++ সম্পর্কে। উত্তরগুলির অনেকগুলি স্মার্ট পয়েন্টারগুলির মতো জিনিসগুলির উপর নির্ভর করে, যা সি ++ এ উপলব্ধ নয়।
অ্যাড্রিয়ান ম্যাকার্থি

উত্তর:


86

0 এ একটি পয়েন্টার সেট করা (যা স্ট্যান্ডার্ড সি ++ এ "নাল", সি থেকে ন্যূনাল সংজ্ঞাটি কিছুটা আলাদা) ডাবল ডিলিটগুলিতে ক্রাশ হওয়া এড়ানো যায়।

নিম্নোক্ত বিবেচনা কর:

Foo* foo = 0; // Sets the pointer to 0 (C++ NULL)
delete foo; // Won't do anything

যেখানে:

Foo* foo = new Foo();
delete foo; // Deletes the object
delete foo; // Undefined behavior 

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

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

অবশেষে, অবজেক্ট বরাদ্দ পরিচালনার বিষয়ে একটি বিভাজন, আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি আপনার প্রয়োজনের উপর নির্ভর করে std::unique_ptrকঠোর / একক মালিকানা, std::shared_ptrভাগ করে নেওয়া মালিকানার জন্য, বা অন্য স্মার্ট পয়েন্টার বাস্তবায়নটি একবার দেখুন।


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

28
এখানে সমস্যাটি হ'ল আপনার ডাবল মুছুন। পয়েন্টারটি NULL তৈরি করা কেবল এই সত্যটি লুকিয়ে রাখে যে এটি এটি সংশোধন করে না বা এটিকে কোনও নিরাপদ করে না। একবছর পরে ফিরে আসছেন এবং ফু মুছে দেখছেন এমন এক মেইনাইনার কল্পনা করুন। তিনি এখন বিশ্বাস করেন যে তিনি পয়েন্টারটি পুনরায় ব্যবহার করতে পারেন দুর্ভাগ্যক্রমে তিনি দ্বিতীয় মুছাটি মিস করতে পারেন (এটি এমনকি একই ফাংশনেও নাও থাকতে পারে) এবং এখন পয়েন্টারের পুনরায় ব্যবহার এখন দ্বিতীয় মুছলে ট্র্যাশ হয়ে যায়। দ্বিতীয় মোছার পরে যে কোনও অ্যাক্সেস এখন একটি বড় সমস্যা।
মার্টিন ইয়র্ক

11
NULLডাবল মোছার ত্রুটিটি মাস্ক করতে পয়েন্টারটির সেটিংসটি সত্য । (কেউ কেউ এই মুখোশটিকে প্রকৃতপক্ষে সমাধান হিসাবে বিবেচনা করতে পারে - এটি সমস্যা, তবে এটি খুব ভাল নয় কারণ এটি সমস্যার মূলের কাছে যায় না)) তবে এটিকে নূলে মুখোমুখি করা না করা (FAR!) আরও মুছে ফেলার পরে ডেটা অ্যাক্সেস করার সাধারণ সমস্যা।
অ্যাড্রিয়ান ম্যাকার্থি 0

আফাইক, স্ট্যান্ড :: অটো_সিপিআর আসন্ন সি ++ স্ট্যান্ডার্ড
রাফাক

আমি অবহেলিত বলব না, এটি ধারণাটি সবেমাত্র চলে যাওয়ার মতো করে তোলে। পরিবর্তে, এটি স্থানান্তরিত হচ্ছে unique_ptr, যা auto_ptrপদক্ষেপ শব্দার্থক দ্বারা যা করার চেষ্টা করেছিল does
GManNickG

55

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

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

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


15
সুতরাং আপনি যুক্তি দিচ্ছেন যে সেখানে প্রথমে কোনও কাঁচা পয়েন্টার না থাকা উচিত ছিল এবং পয়েন্টারকে জড়িত কিছু বলে "ভাল অনুশীলন" শব্দটি দিয়ে আশীর্বাদ করা উচিত নয়? যথেষ্ট ফর্সা।
মার্ক র্যানসোম

7
ভাল, কম বা কম। আমি বলতে হবে কিছুই একটি কাঁচা পয়েন্টার সাথে সংশ্লিষ্ট একটি ভাল অভ্যাস বলা যেতে পারে। নিয়মের চেয়ে এটি ব্যতিক্রম। সাধারণত, পয়েন্টারের উপস্থিতি একটি সূচক যে গভীর স্তরে কিছু ভুল আছে।
jalf

3
কিন্তু তাৎক্ষণিক প্রশ্নের উত্তর দিতে, না, আমি কিভাবে নাল পয়েন্টার সেট করতে পারেন কি কখনো দেখতে না কারণ ত্রুটি।
jalf

7
আমি একমত নই - এমন একটি মামলা রয়েছে যখন কোনও পয়েন্টার ব্যবহার করা ভাল। উদাহরণস্বরূপ, স্ট্যাকে 2 টি ভেরিয়েবল রয়েছে এবং আপনি এর মধ্যে একটি চয়ন করতে চান। অথবা আপনি কোনও ফাংশনে alচ্ছিক পরিবর্তনশীলটি পাস করতে চান। আমি বলব, আপনার সাথে কখনও কোনও কাঁচা পয়েন্টার ব্যবহার করা উচিত নয় new
rlbond

4
যখন একটি পয়েন্টার সুযোগ মধ্য থেকে বের হয়ে, আমি কেমন দেখতে না কিছু তা মোকাবেলা করার কেউ যথাসাধ্য প্রয়োজন নেই।
জলফ

43

আমি আরও ভাল একটি অনুশীলন পেয়েছি: যেখানে সম্ভব, ভেরিয়েবলের সুযোগটি শেষ করুন!

{
    Foo* pFoo = new Foo;
    // use pFoo
    delete pFoo;
}

17
হ্যাঁ, RAII আপনার বন্ধু। এটি একটি ক্লাসে আবদ্ধ করুন এবং এটি আরও সহজ হয়ে ওঠে। বা এসটিএল ব্যবহার করে নিজেকে মেমরি মোটেই হ্যান্ডেল করবেন না!
ব্রায়ান

24
হ্যাঁ, এটি সর্বোত্তম বিকল্প। যদিও প্রশ্নের উত্তর দেয় না।
মার্ক মুক্তিপুষ্ট

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

2
এটি ভাবতে আসুন, আপনি যদি এটি করতে পারতেন তবে কেন আপনি কেবল স্তূপটি ভুলে আপনার সমস্ত স্মৃতিটিকে স্ট্যাকের বাইরে টানবেন না?
সান জ্যাকিন্টো

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

31

আমি সর্বদা পয়েন্টার সেট করে NULL(এখন nullptr) এটি অবজেক্ট (গুলি) মুছে ফেলার পরে।

  1. এটি মুক্ত মেমরির অনেকগুলি রেফারেন্স ধরতে সহায়তা করতে পারে (আপনার প্ল্যাটফর্মের ত্রুটিগুলি নাল পয়েন্টারের একটি ডিরিফের উপরে ধরে)।

  2. এটি ফ্রি'ড মেমোরির সমস্ত রেফারেন্স ধরতে পারে না, উদাহরণস্বরূপ, আপনার কাছে পয়েন্টারের কপি থাকলে lying তবে কিছু কিছু কারও চেয়ে ভাল।

  3. এটি একটি ডাবল-মোছার মুখোশ দেবে, তবে আমি দেখতে পেয়েছি যে এগুলি ইতিমধ্যে মুক্ত মেমরির অ্যাক্সেসের চেয়ে খুব কম সাধারণ।

  4. অনেক ক্ষেত্রে সংকলক এটি অপ্টিমাইজ করতে চলেছে। সুতরাং যুক্তি যে এটি অপ্রয়োজনীয় আমাকে প্ররোচিত করে না।

  5. আপনি যদি ইতিমধ্যে RAII ব্যবহার করে থাকেন তবে deleteআপনার কোডে শুরু করার মতো অনেকগুলি নেই , তাই অতিরিক্ত অ্যাসাইনমেন্টটি বিশৃঙ্খলা সৃষ্টি করে এমন যুক্তি আমাকে প্ররোচিত করে না।

  6. এটি প্রায়শই সুবিধাজনক, ডিবাগ করার সময়, একটি বাসি পয়েন্টারের চেয়ে নাল মানটি দেখতে।

  7. এটি যদি এখনও আপনাকে বিরক্ত করে তোলে তবে তার পরিবর্তে স্মার্ট পয়েন্টার বা একটি রেফারেন্স ব্যবহার করুন।

আমি অন্য ধরণের রিসোর্স হ্যান্ডলগুলি নো-রিসোর্স মানতে সেট করে থাকি যখন রিসোর্সটি ফ্রি হয়ে যায় (যা সাধারণত কেবলমাত্র একটি RAII র‌্যাপারের সংস্থাপকটিতে সংস্থান করে থাকে)।

আমি একটি বৃহত (9 মিলিয়ন স্টেটমেন্ট) বাণিজ্যিক পণ্য (মূলত সি তে) নিয়ে কাজ করেছি। এক পর্যায়ে, মেমরিটি মুক্ত হওয়ার সময় আমরা পয়েন্টারটি বাতিল করতে ম্যাক্রো যাদু ব্যবহার করি। এটি অবিলম্বে স্থির করা হয়েছে যে প্রচুর লুক্কায়িত বাগ উন্মুক্ত। আমি যতদূর মনে করতে পারি, আমাদের কখনও ডাবল-ফ্রি বাগ ছিল না।

আপডেট: মাইক্রোসফ্ট বিশ্বাস করে যে এটি সুরক্ষার জন্য একটি ভাল অনুশীলন এবং তাদের এসডিএল নীতিগুলিতে অনুশীলনের প্রস্তাব দেয়। দৃশ্যত এমএসভিসি ++ 11 মুছে ফেলা পয়েন্টারটি স্বয়ংক্রিয়ভাবে (অনেক পরিস্থিতিতে) স্টম্প করবে যদি আপনি / এসডিএল বিকল্পটি সংকলন করেন।


12

প্রথমত, এগুলি এবং ঘনিষ্ঠভাবে সম্পর্কিত বিষয়গুলিতে প্রচুর বিদ্যমান প্রশ্ন রয়েছে, উদাহরণস্বরূপ কেন পয়েন্টারটিকে NULL এ সেট করে না?

আপনার কোডটিতে, কী চলছে তা ইস্যু (পি ব্যবহার করুন)। উদাহরণস্বরূপ, কোথাও আপনার যদি এই জাতীয় কোড থাকে:

Foo * p2 = p;

তারপরে NULL তে পি সেট করা খুব সামান্যই সাফল্য অর্জন করে, কারণ আপনার এখনও চিন্তার পয়েন্টার পি 2 রয়েছে।

এর অর্থ এই নয় যে NULL এ একটি পয়েন্টার সেট করা সর্বদা অর্থহীন। উদাহরণস্বরূপ, যদি পি কোনও সদস্যের পরিবর্তে যদি এমন কোনও উত্সকে নির্দেশিত করে যাঁর জীবদ্দশায় জীবদ্দশায় পি রয়েছে এমন শ্রেণীর মতো না হয়, তবে NUL এ পি সেট করা সংস্থানটির উপস্থিতি বা অনুপস্থিতি নির্দেশ করার একটি কার্যকর উপায় হতে পারে।


1
আমি সম্মত হই যে এমন সময়গুলি কখনই সহায়তা করে না তবে আপনি মনে করেন যে এটি সক্রিয়ভাবে ক্ষতিকারক হতে পারে। এটি কি আপনার উদ্দেশ্য ছিল, না আমি এটি ভুল পাঠ করেছি?
মার্ক র্যানসম

1
পয়েন্টারটির কোনও অনুলিপি পয়েন্টার ভেরিয়েবলটি NULL এ সেট করা উচিত কিনা এই প্রশ্নের সাথে অপ্রাসঙ্গিক কিনা। রাতের খাবার খাওয়ার পরে খাবারগুলি পরিষ্কার করার একই ভিত্তিতে এটিকে NULL তে সেট করা একটি ভাল অনুশীলন - যদিও কোনও কোড থাকতে পারে এমন সমস্ত বাগের বিরুদ্ধে এটি কোনও সুরক্ষার ব্যবস্থা নয়, এটি ভাল কোডের স্বাস্থ্যের প্রচার করে does
ফ্রেঞ্চি পেনোভ

2
@ ফ্রেঞ্চি অনেক লোক আপনার সাথে একমত নয় বলে মনে হচ্ছে। এবং যদি অনুলিপিটি মুছে ফেলার পরে আপনি অনুলিপিটি ব্যবহার করার চেষ্টা করেন তবে অবশ্যই একটি অনুলিপি রয়েছে কিনা তা প্রাসঙ্গিক।

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

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

7

এর পরে যদি আরও কোড থাকে delete হ্যাঁ। যখন পয়েন্টারটি কোনও কনস্ট্রাক্টরে বা পদ্ধতি বা ফাংশনের শেষে মুছে ফেলা হয়, না No.

এই দৃষ্টান্তটির মূল বক্তব্যটি হ'ল প্রোগ্রামারটিকে রান-সময় চলাকালীন মনে করিয়ে দেওয়া উচিত যে অবজেক্টটি ইতিমধ্যে মুছে ফেলা হয়েছে।

আরও ভাল অনুশীলন হ'ল স্মার্ট পয়েন্টার (ভাগ করা বা স্কোপড) ব্যবহার করা যা স্বয়ংক্রিয়ভাবে তাদের টার্গেটের অবজেক্টগুলি মুছে দেয়।


সকলেই (মূল প্রশ্নকারী সহ) সম্মত হন যে স্মার্ট পয়েন্টারগুলি যাওয়ার উপায়। কোড বিকশিত হয়। আপনি যখন প্রথমে এটি ঠিক করবেন তখন মোছার পরে আর কোনও কোড নাও থাকতে পারে তবে সময়ের সাথে সাথে এটির পরিবর্তন হওয়ার সম্ভাবনা রয়েছে। অ্যাসাইনমেন্টটি রাখা যখন তা ঘটে তখন সহায়তা করে (এবং মাঝামাঝি সময়ে প্রায় কোনও কিছুই ব্যয় করে না)।
অ্যাড্রিয়ান ম্যাকার্থি

3

অন্যরা যেমন বলেছে, delete ptr; ptr = 0;আপনার নাক থেকে অসুরদের উড়ে যাওয়ার কারণ নয়। তবে এটি ptrবিভিন্ন ধরণের পতাকা হিসাবে ব্যবহারকে উত্সাহ দেয় । কোডটি ফাঁক হয়ে যায় deleteএবং পয়েন্টারটি সেট করে NULL। পরবর্তী পদক্ষেপটি হ'ল if (arg == NULL) return;কোনও NULLপয়েন্টারের দুর্ঘটনাজনিত ব্যবহারের বিরুদ্ধে সুরক্ষার জন্য আপনার কোডটি ছড়িয়ে দেওয়া । একবার চেক করলে সমস্যাটি ঘটেNULLকোনও সমস্যা বা প্রোগ্রামের স্থিতির জন্য আপনার প্রাথমিক ।

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


9
পয়েন্টারটিকে পতাকা হিসাবে ব্যবহারে কোনও ভুল নেই। আপনি যদি কোনও পয়েন্টার ব্যবহার করে থাকেন এবং NULLকোনও বৈধ মান না হয় তবে আপনার পরিবর্তে সম্ভবত একটি রেফারেন্স ব্যবহার করা উচিত।
অ্যাড্রিয়ান ম্যাকার্থি 0

2

আমি আপনার প্রশ্নটি সামান্য পরিবর্তন করব:

আপনি কি একটি বিনীতীত পয়েন্টার ব্যবহার করবেন? আপনি কি জানেন যে, আপনি NULL তে সেট করেননি বা মেমরিটি এটির জন্য বরাদ্দ করেন নি?

দুটি পরিস্থিতি রয়েছে যেখানে পয়েন্টারটি NUL এ সেট করা এড়িয়ে যেতে পারে:

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

এদিকে, NUL- এ পয়েন্টার সেট করা আমার পক্ষে ত্রুটিগুলি আড়াল করতে পারে এমন তর্ক করার মতো মনে হচ্ছে আপনার কোনও বাগ ঠিক করা উচিত নয় কারণ এই ফিক্সটি অন্য কোনও বাগ লুকিয়ে রাখতে পারে। কেবলমাত্র বাগগুলি যা পয়েন্টারটি NULL তে সেট না করা হলে প্রদর্শিত হতে পারে সেইগুলিই পয়েন্টারটি ব্যবহার করার চেষ্টা করবে। তবে এটিকে নূলে সেট করা প্রকৃতপক্ষে ঠিক একই বাগের কারণ হতে পারে যদি আপনি এটি মুক্ত মেমরির সাথে ব্যবহার করেন, তা না?


(ক) "আপনার বাগটি ঠিক করা উচিত নয় এমন যুক্তি দেওয়ার মতো শব্দগুলি" এনইউএলএলকে পয়েন্টার সেট না করা কোনও বাগ নয়। (খ) "তবে এটি এনএলএল-এ সেট করা আসলে ঠিক একই বাগের কারণ হতে পারে" না ন্যূনএলএল সেট করা ডাবল মুছনাকে আড়াল করে । (গ) সংক্ষিপ্তসার: এনএইউএল-তে সেট করা ডাবল মুছনাকে আড়াল করে, তবে বাসি রেফারেন্সগুলি প্রকাশ করে। NULL এ সেট না করা বাসি রেফারেন্সগুলি গোপন করতে পারে তবে ডাবল মুছে ফেলা হবে। উভয় পক্ষই একমত যে আসল সমস্যাটি হল বাসি-রেফারেন্সগুলি এবং ডাবল-মোছা ঠিক করা।
হাঁস 14

2

আপনার যদি অন্য কোনও প্রতিবন্ধকতা না থাকে যা আপনাকে মুছে ফেলার পরে পয়েন্টারটি সেট করতে বা সেট করতে বাধ্য করে না (মুছে ফেলার পরে এই জাতীয় একটি বাধা নিল বাটারওয়ার্থ উল্লেখ করেছিলেন ), তবে আমার ব্যক্তিগত পছন্দটি এটিকে ছেড়ে দেওয়া।

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

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


2

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

যদি আপনি প্রকৃতপক্ষে এটিই বোঝাতে চান তবে উত্স: alচ্ছিক কিছু ব্যবহার করে উত্সটিতে সেই স্পষ্ট করা আরও ভাল

optional<Foo*> p (new Foo);
// (use p.get(), but must test p for truth first!...)
delete p.get();
p = optional<Foo*>();

তবে যদি আপনি সত্যিই লোকেরা জানতে চেয়েছিলেন যে পয়েন্টারটি "খারাপ হয়েছে", আমি তাদের সাথে 100% চুক্তি করব যাঁরা সবচেয়ে ভাল কাজটি করেন তা এটিকে সুযোগের বাইরে চলে যায়। তারপরে আপনি রানটাইমগুলিতে খারাপ ডিসেরেন্সের সম্ভাবনা রোধ করতে সংকলকটি ব্যবহার করছেন।

এটি সমস্ত সি ++ স্নানের জলের শিশু, এটি বাইরে ফেলে দেওয়া উচিত নয়। :)


2

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

দায়িত্ব অর্পণের বিরুদ্ধে যুক্তিযুক্ত অনেকগুলি 0পরামর্শ দেয় যে এটি পারে কোনও বাগ লুকিয়ে রাখতে বা নিয়ন্ত্রণ প্রবাহকে জটিল করে তুলতে পারে। মূলত, এটি হয় একটি প্রবাহ ত্রুটি (আপনার ত্রুটি নয় (খারাপ তুষের জন্য দুঃখিত)) বা প্রোগ্রামারের পক্ষে অন্য কোনও ত্রুটি - সম্ভবত এমন একটি ইঙ্গিতও রয়েছে যে প্রোগ্রাম প্রবাহ খুব জটিল হয়ে উঠেছে।

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

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

সেখান থেকে আপনার কেবলমাত্র খুব সীমিত সুযোগ এবং প্রসঙ্গ রয়েছে যেখানে নাল পয়েন্টার উপস্থিত থাকতে পারে (বা অনুমোদিত)।

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

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


1

আপনি ইতিমধ্যে আপনার প্রশ্নে যা রেখেছেন তা আমাকে প্রসারিত করুন।

বুলেট-পয়েন্ট আকারে আপনি নিজের প্রশ্নে যা লিখেছেন তা এখানে:


মুছে ফেলার পরে NULL তে পয়েন্টার সেট করা সি ++ তে সর্বজনীন ভাল অনুশীলন নয়। সময় আছে যখন:

  • এটা করা ভাল জিনিস
  • এবং সময়গুলি যখন অর্থহীন এবং ত্রুটিগুলি আড়াল করতে পারে।

যাইহোক, এই খারাপ যখন কোন সময় আছে ! আপনি হবে না স্পষ্টভাবে এটি nulling দ্বারা আরো বাগ পরিচয় করিয়ে, তাই না হবে লিক মেমরি, আপনি না করবে না কারণ অনির্ধারিত আচরণ ঘটতে।

সুতরাং, যদি সন্দেহ হয়, কেবল এটি বাতিল করুন।

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


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

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

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

@ মাইক এমবি আমি সম্পূর্ণরূপে একমত, এই সম্পর্কে আমার মতামত গত ~ .5.৫ বছরে যথেষ্ট পরিবর্তিত হয়েছে
কারসন মায়ার্স

প্রোগ্রামার হওয়ার ক্ষেত্রে, আমরা 6--7 বছর আগে আমরা সবাই অন্য কেউ ছিলাম :) আমি এমনকি নিশ্চিত নই যে আমি আজ কোনও সি / সি ++ প্রশ্নের উত্তর দেওয়ার সাহস করতাম :)
ল্যাসে ভি কার্লসেন

1

হ্যাঁ.

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

আপনি এটা করতে না থাকে, তাহলে আপনি হবে কিছু কদর্য পয়েন্টার derefernce বাগ এক দিন আছে।

আমি সর্বদা মুছে ফেলার জন্য ম্যাক্রো ব্যবহার করি:

#define SAFEDELETE(ptr) { delete(ptr); ptr = NULL; }

(এবং একটি অ্যারের জন্য সমান, বিনামূল্যে (), হ্যান্ডলগুলি প্রকাশ করে)

আপনি "স্ব মুছুন" পদ্ধতিগুলিও লিখতে পারেন যা কলিং কোডের পয়েন্টারটির একটি রেফারেন্স নেয়, তাই তারা কলিং কোডের পয়েন্টারটিকে NULL এ জোর করে। উদাহরণস্বরূপ, অনেকগুলি অবজেক্টের একটি সাবট্রি মুছতে:

static void TreeItem::DeleteSubtree(TreeItem *&rootObject)
{
    if (rootObject == NULL)
        return;

    rootObject->UnlinkFromParent();

    for (int i = 0; i < numChildren)
       DeleteSubtree(rootObject->child[i]);

    delete rootObject;
    rootObject = NULL;
}

সম্পাদন করা

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

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

অবশ্যই, উপরের উদাহরণটি একটি অটো-পয়েন্টারের দিকে মাত্র এক ধাপ। যা আমি প্রস্তাব দিইনি কারণ ওপি বিশেষত একটি অটো পয়েন্টার ব্যবহার না করার ক্ষেত্রে জিজ্ঞাসা করেছিল।


2
ম্যাক্রোস একটি খারাপ ধারণা, বিশেষত যখন তারা সাধারণ ফাংশনগুলির মতো দেখায়। আপনি যদি এটি করতে চান তবে একটি টেম্প্লেটেড ফাংশন ব্যবহার করুন।

2
বাহ ... আমি পয়েন্টারকে anObject->Delete(anObject)অবৈধ করার মতো কোনও কিছুই দেখিনি anObject। এটা কেবল ভীতিজনক। আপনার এটির জন্য একটি স্থিতিশীল পদ্ধতি তৈরি করা উচিত যাতে আপনাকে TreeItem::Delete(anObject)খুব কম সময়ে করতে বাধ্য করা হবে ।
ডি.শ্যাওলি

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

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

1

"এমন সময় আছে যখন এটি করা ভাল কাজ এবং সময় যখন এটি অর্থহীন এবং ত্রুটিগুলি আড়াল করতে পারে"

আমি দুটি সমস্যা দেখতে পাচ্ছি: সেই সাধারণ কোড:

delete myObj;
myobj = 0

মাল্টিথ্রেডেড পরিবেশে একটি লাইনারে পরিণত হয়:

lock(myObjMutex); 
delete myObj;
myobj = 0
unlock(myObjMutex);

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

আর একটি বিপদ ব্যতিক্রম-ব্যবহার কোডে এই কৌশলটির উপর নির্ভর করছে:

try{  
   delete myObj; //exception in destructor
   myObj=0
}
catch
{
   //myObj=0; <- possibly resource-leak
}

if (myObj)
  // use myObj <--undefined behaviour

এই জাতীয় কোডে হয় আপনি রিসোর্স-লিক তৈরি করেন এবং সমস্যাটি স্থগিত করুন বা প্রক্রিয়া ক্র্যাশ।

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


আমি দেখতে ব্যর্থ হয়েছি, কীভাবে 4-লাইনার 3-লাইনারের চেয়ে উল্লেখযোগ্যভাবে আরও জটিল (কোনওভাবেই লক_গার্ড ব্যবহার করা উচিত) এবং যদি আপনার ডেস্ট্রাক্টর নিক্ষেপ করে তবে আপনি যে কোনও উপায়ে সমস্যায় পড়েছেন।
মাইক এমবি

যখন আমি এই উত্তরটি প্রথম দেখলাম তখন বুঝতে পারিনি যে আপনি কেন একজন বিনষ্টকারীতে কোনও পয়েন্টার বাতিল করতে চান, তবে এখন আমি এটি করি - এটি সেই ক্ষেত্রে যেখানে পয়েন্টারের মালিকানাধীন অবজেক্টটি মুছে ফেলার পরে ব্যবহৃত হয়ে যায়!
মার্ক

0

উদ্বিগ্ন হওয়ার জন্য সবসময় ঝাঁকুনি পয়েন্টার রয়েছে


1
"এই" এর পরিবর্তে "ঝুঁকিপূর্ণ পয়েন্টার" লাগানো কি এত কঠিন হবে? :) অন্তত এটি আপনার উত্তর কিছু পদার্থ দেয়।
GManNickG

4
এটি এমনকি ডব্লিউ 3 সি
কিউ

0

আপনি যদি পয়েন্টারটি আবার ব্যবহার করার আগে পুনরায় গণনা করতে যাচ্ছেন (এটি নির্ধারণ করা, এটি কোনও ফাংশনে প্রেরণ করা ইত্যাদি), পয়েন্টারটিকে NUL তৈরি করা কেবল একটি অতিরিক্ত ক্রিয়াকলাপ। যাইহোক, আপনি যদি নিশ্চিত না হন যে এটি আবার ব্যবহারের আগে এটি পুনরায় স্থানান্তরিত হবে কি না, এটি NUL এ সেট করা ভাল ধারণা।

যেমনটি অনেকে বলেছেন, কেবলমাত্র স্মার্ট পয়েন্টার ব্যবহার করা আরও সহজ।

সম্পাদনা: থমাস ম্যাথিউস যেমন পূর্বের উত্তরে বলেছিলেন যে কোনও পয়েন্টার যদি কোনও ডেস্ট্রাক্টর্টারে মুছে ফেলা হয় তবে এটিতে NULL বরাদ্দ করার কোনও প্রয়োজন নেই কারণ এটি আবার ব্যবহার করা হবে না কারণ বস্তুটি ইতিমধ্যে ধ্বংস হয়ে গেছে।


0

আমি কল্পনা করতে পারি NUL এ মুছে ফেলার পরে এটি কার্যকর হয়ে যাওয়ার পরে বিরল ক্ষেত্রে যেখানে এটি কোনও একক ফাংশনে (বা অবজেক্ট) পুনরায় ব্যবহার করার বৈধ দৃশ্য রয়েছে। অন্যথায় এটি কোনও অর্থবোধ করে না - একটি পয়েন্টারটির যতক্ষণ না এটি উপস্থিত থাকে - সময়কাল পর্যন্ত অর্থবহ কিছুকে নির্দেশ করতে হবে point


0

কোডটি যদি আপনার আবেদনের সর্বাধিক পারফরম্যান্স-সমালোচনামূলক অংশের অন্তর্ভুক্ত না থাকে তবে এটিকে সহজ রাখুন এবং একটি শেয়ার্ড_পিটার ব্যবহার করুন:

shared_ptr<Foo> p(new Foo);
//No more need to call delete

এটি রেফারেন্স গণনা সম্পাদন করে এবং থ্রেড-নিরাপদ। আপনি এটি tr1 (std :: tr1 নেমস্পেস, # অন্তর্ভুক্ত <মেমরি>) এ খুঁজে পেতে পারেন বা যদি আপনার সংকলক এটি সরবরাহ না করে তবে তা বুস্ট থেকে পান।

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