এটি একটি নাল পয়েন্টার মুছে ফেলা নিরাপদ?


299

এটি একটি নাল পয়েন্টার মুছে ফেলা নিরাপদ?

এবং এটি কি একটি ভাল কোডিং শৈলী?


21
ভাল অনুশীলন হ'ল একক কল ছাড়াই সি ++ প্রোগ্রাম লিখুন delete। ব্যবহারের RAII পরিবর্তে। এটির std::vector<T> v(100);পরিবর্তে ব্যবহার করুন T* p = new T[100];, স্মার্ট পয়েন্টারগুলি ব্যবহার করুন unique_ptr<T>এবং shared_ptr<T>এটি কাঁচা পয়েন্টার ইত্যাদির পরিবর্তে মুছে ফেলার যত্ন নিন
ফ্রেডওভারফ্লো

8
ধন্যবাদ make_shared(C ++ 11) এবং make_unique(C ++ 14) আপনার প্রোগ্রাম থাকা উচিত শূন্য এর newএবংdelete
sp2danny

2
এখনও কিছু দুর্লভ কেস থাকতে পারে যার জন্য নতুন / মুছার প্রয়োজন হয়, যেমন পারমাণবিক <টি *>: পারমাণবিক <অনন্য_আপনার <টি>> অনুমোদিত নয় এবং পারমাণবিক <শেয়ার_ptr <T>> এর ওভারহেড রয়েছে যা কিছু ক্ষেত্রে অগ্রহণযোগ্য হতে পারে।
atb

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

2
@ ভিনগার্সিয়া মূল বিষয়টি হ'ল বেশিরভাগ ব্যবহারকারী / ক্লায়েন্ট (এটি: গ্রন্থাগারহীন) কোডটি কখনই লিখতে হবে না newবা delete। সংস্থানগুলি পরিচালনা করার জন্য ডিজাইন করা ক্লাসগুলি, যেখানে স্ট্যান্ডার্ড উপাদানগুলি কাজটি করতে পারে না, অবশ্যই তাদের যা করা দরকার তা করতে পারে, তবে মূল বিষয়টি হ'ল তারা কুশরী জিনিসগুলি তাদের মেমরির সাথে পরিচালনা করে, শেষ ব্যবহারকারী কোড নয় user সুতরাং, আপনার নিজের লাইব্রেরি / সাহায্যকারী বর্গ করতে করতে new/ delete, এবং তাদের পরিবর্তে যে বর্গ ব্যবহার করুন।
আন্ডারস্কোর_

উত্তর:


265

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

আমিও চাই যদি deleteডিফল্টরূপে NULL এ প্যারামিটারটি সেট করা থাকে

#define my_delete(x) {delete x; x = NULL;}

(আমি আর এবং এল মান সম্পর্কে জানি, তবে এটি কি সুন্দর হবে না?)


72
মনে রাখবেন যে এখনও মুছে ফেলার জন্য যদি আপনি NULL তে সেট করেন তবে একই বস্তুটির দিকে আরও অনেক পয়েন্টার ইঙ্গিত করতে পারে।
sth

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

142
একটি খুব godশ্বরের অনুশীলন মুছে ফেলার পরে NULL তে পয়েন্টার সেট করছে না । মোছার পরে NULL তে একটি পয়েন্টার সেট করা মেমরির বরাদ্দ ত্রুটিকে মাস্ক্রাইড করে, যা খুব খারাপ জিনিস। একটি প্রোগ্রাম যা সঠিক তা দু'বার পয়েন্টার মুছবে না এবং যে প্রোগ্রামটি পয়েন্টারটিকে দু'বার মুছে ফেলবে তা ক্রাশ হওয়া উচিত
দামন

15
@ অ্যালিস: মান যে বিষয়ে সম্মান জানায় এটি অপ্রাসঙ্গিক। 30 বছর আগে কোনও অযৌক্তিক কারণে নাল পয়েন্টার মোছার মানটি সংজ্ঞায়িত হয়েছে, সুতরাং এটি আইনী (সম্ভবত একটি সি উত্তরাধিকার) is তবে একই পয়েন্টারটি দু'বার মুছে ফেলা (এমনকি এর বিট প্যাটার্ন পরিবর্তন করার পরেও) এখনও একটি গুরুতর প্রোগ্রাম ত্রুটি। স্ট্যান্ডার্ড শব্দটি দ্বারা নয়, প্রোগ্রাম যুক্তি এবং মালিকানা দ্বারা। যেমন নাল পয়েন্টার মুছে ফেলা হচ্ছে, যেহেতু নাল পয়েন্টারটি কোনও বস্তুর সাথে মিলে যায় তাই কোনও কিছুই সম্ভবত মুছে ফেলা যায় না। একটি প্রোগ্রাম আবশ্যক ঠিক যদি একটি বস্তু বৈধ এবং যারা এটি মালিক জানেন, এবং যখন এটি মুছে ফেলা যাবে।
দামন

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

77

সি ++ 0x খসড়া স্ট্যান্ডার্ড থেকে।

$ 5.3.5 / 2 - "[...] যে কোনও বিকল্পে মুছার অপারেন্ডের মান একটি নাল পয়েন্টার মান হতে পারে [[... '"

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

একদিকে যেমন, সি স্ট্যান্ডার্ড $ 7.20.3.2 এও বলেছে যে একটি নল পয়েন্টারে 'ফ্রি' কোনও ক্রিয়া করে না।

ফ্রি ফাংশন পিটিআর দ্বারা নির্দেশিত স্থানটির অবনতি ঘটায় যার অর্থ আরও বরাদ্দের জন্য উপলব্ধ করা হয়। যদি পিটিআরটি নাল পয়েন্টার হয় তবে কোনও ক্রিয়া ঘটে না।


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

47

হ্যাঁ এটি নিরাপদ।

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


যেহেতু পূর্ববর্তী বাক্যটি বিভ্রান্তির সৃষ্টি করেছে, উদাহরণ - যা ব্যতিক্রমী নয় - যা বর্ণনা করা হচ্ছে তার থেকে:

void somefunc(void)
{
    SomeType *pst = 0;
    AnotherType *pat = 0;

    
    pst = new SomeType;
    
    if (…)
    {
        pat = new AnotherType[10];
        
    }
    if (…)
    {
        code using pat sometimes
    }

    delete[] pat;
    delete pst;
}

সমস্ত ধরণের নীট রয়েছে যা নমুনা কোডের সাথে বাছাই করা যায়, তবে ধারণাটি (আমি আশা করি) পরিষ্কার। পয়েন্টার ভেরিয়েবলগুলি শূন্যে শুরু করা হয় যাতে deleteফাংশন শেষে ক্রিয়াকলাপগুলি সোর্স কোডে নন-নাল কিনা তা পরীক্ষা করার প্রয়োজন হয় না; লাইব্রেরি কোড যেভাবেই পরীক্ষা করে।


আমি এটি কয়েকবার বুঝতে পেরেছিলাম। আপনার অবশ্যই তাদের বোঝা উচিত পদ্ধতিটির শীর্ষে শূন্যে শুরু করা, বা এটির সময়, লেজে নয়, অবশ্যই? অন্যথায় আপনি কেবল শূন্য এবং মুছুন উভয়ই মুছে ফেলবেন।
লার্নের মারকুইস

1
@EJP: একটি ফাংশন একটি বিলকুল অকল্পনীয় না রূপরেখা হতে পারে: void func(void) { X *x1 = 0; Y *y1 = 0; … x1 = new[10] X; … y1 = new[10] Y; … delete[] y1; delete[] x1; }। আমি কোনও ব্লক কাঠামো বা জাম্প দেখিয়েছি না, তবে delete[]প্রারম্ভিক আরম্ভের কারণে শেষের কাজগুলি নিরাপদ। যদি কিছু x1বরাদ্দ হওয়ার পরে শেষের দিকে ঝাঁপিয়ে পড়ে এবং বরাদ্দ দেওয়ার আগে y1এবং এর কোনও সূচনা না হয় y1, তবে সেখানে সংজ্ঞায়িত আচরণ হতে হবে - এবং কোডটি মুছে ফেলার আগে শূন্যতার ( x1এবং এর y1) জন্য পরীক্ষা করতে পারে, সেখানে করার দরকার নেই তাই।
জোনাথন লেফলার

22

নাল পয়েন্টার মোছার কোনও প্রভাব নেই। এটি প্রয়োজনীয় কোডিং স্টাইলটি প্রয়োজনীয় নয় কারণ এটি প্রয়োজন হয় না তবে এটি খারাপও নয়।

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


20
লোকেরা ন্যূনাল পয়েন্টারটি মুছতে চায় এমন সময় যখন তারা নিশ্চিত হয় না যে এতে নুল রয়েছে কিনা ... যদি তারা জানত যে এটি নুল ছিল তবে তারা মোছার বিষয়টি বিবেচনা করবে না এবং তাই জিজ্ঞাসা করবে ;-)।
টনি ডেলরয়

@ টনি: আমার বক্তব্যটি কেবলমাত্র এটিই ছিল যে এটির কোনও প্রভাব থাকবে না এবং এমন কোডের উপস্থিতি একটি পয়েন্টারটিকে মুছে দেয় যা কখনও কখনও নূআলএল থাকে অগত্যা খারাপ নয়।
ব্রায়ান আর। বন্ডি

3
কর্মক্ষমতা, পঠনযোগ্যতা এবং রক্ষণাবেক্ষণযোগ্যতার জন্য আইএমও রিডানড্যান্ট চেকগুলি অবশ্যই খারাপ।
পলম

@ পলম ওপি অবশ্যই সে ধরণের খারাপ, সেগ ফাল্ট / ইউবি ধরণের আরও খারাপ বিষয়ে কথা বলছে না।
শীতকাল


3

আপনি মুছে ফেলা অপারেটরটি ওভারলোড না করলেই এটি নিরাপদ। যদি আপনি মুছে ফেলা অপারেটরটি ওভারলোড করে থাকেন এবং নাল শর্তটি পরিচালনা করছেন না তবে এটি মোটেই নিরাপদ নয়।


আপনি আপনার উত্তরের জন্য কোনও ব্যাখ্যা যোগ করতে পারেন?
মার্সিন নাবিয়ায়েক

-2

আমি অভিজ্ঞ যে এটি না [] NULL (অর্থাৎ অ্যারে সিনট্যাক্স) মুছে ফেলা নিরাপদ (VS2010)। এটি সি ++ স্ট্যান্ডার্ড অনুসারে কিনা তা আমি নিশ্চিত নই।

এটা তোলে হয় ডিলিট শূন্য (স্কালে সিনট্যাক্স) এর নিরাপদ।


6
এটি অবৈধ, এবং আমি এটি বিশ্বাস করি না।
কনরাড রুডল্ফ

5
আপনার কোনও নাল পয়েন্টার মুছতে সক্ষম হওয়া উচিত। সুতরাং এটি যদি আপনার জন্য ভঙ্গ হয়, তবে আপনার সম্ভবত কোডটিতে একটি বাগ রয়েছে যা এটি দেখায়।
রহস্যময়

3
Alternative5.3.2 দ্বিতীয় বিকল্পে (অ্যারে মুছুন) মুছে ফেলতে অপারেন্ডের মানটি নাল পয়েন্টার মান বা পয়েন্টার মান হতে পারে যা পূর্ববর্তী অ্যারে নতুন-এক্সপ্রেশন থেকে আসে।
sp2danny

1
@ অপাক্স উত্তরে VS2010 এর আচরণের অভিযোগ রয়েছে। যেমন অন্যান্য মন্তব্যে ব্যাখ্যা করা হয়েছে, এটি নিরাপদ delete[] NULL
কনরাড রুডল্ফ

1
@ অপাক্স সেজন্য আমি "এটি ভুল" এর চেয়ে "আমি বিশ্বাস করি না" লিখেছিলাম। তবে আমি এখনও তা করি না, এবং এটি মানকটির একটি লজ্জাজনক, নির্বোধ লঙ্ঘন হবে। ভিসি ++ স্ট্যান্ডার্ডের বিধিনিষেধ অনুসরণ করার ক্ষেত্রে সাধারণত বেশ ভাল এবং এটি যে জায়গাগুলিতে লঙ্ঘন করে সেগুলি historতিহাসিকভাবে বোঝা যায়।
কনরাড রুডল্ফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.