সি-তে NULL এর জন্য কখন পয়েন্টারগুলি পরীক্ষা করা উচিত?


18

সংক্ষিপ্তসার :

সি এর কোনও ক্রিয়াকলাপটি সর্বদা এটি নিশ্চিত করে যে এটি কোনও NULLপয়েন্টারকে অবজ্ঞা করছে না ? না হলে কখন এই চেকগুলি এড়িয়ে যাওয়া উপযুক্ত?

বিশদ :

আমি প্রোগ্রামিং সাক্ষাত্কার সম্পর্কে কয়েকটি বই পড়ছি এবং আমি ভাবছি সি এর ফাংশন আর্গুমেন্টগুলির জন্য ইনপুট বৈধতার উপযুক্ত ডিগ্রিটি কী? স্পষ্টতই কোনও ফাংশন যা ব্যবহারকারীর কাছ থেকে ইনপুট নেয় তাকে বৈধতা NULLদেওয়ার আগে পয়েন্টারের জন্য পরীক্ষা করা সহ বৈধতা অর্জন করতে হবে । তবে একই ফাইলের মধ্যে এমন কোনও ফাংশনের ক্ষেত্রে কী হবে যা আপনি আপনার API এর মাধ্যমে প্রকাশের প্রত্যাশা করবেন না?

উদাহরণস্বরূপ গিটের উত্স কোডে নিম্নলিখিতটি প্রদর্শিত হবে:

static unsigned short graph_get_current_column_color(const struct git_graph *graph)
{
    if (!want_color(graph->revs->diffopt.use_color))
        return column_colors_max;
    return graph->default_column_color;
}

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

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

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

আমি উত্পাদন কোড লেখার জন্য সাধারণভাবে এই প্রশ্নে আগ্রহী। তবে আমি প্রোগ্রামিং সাক্ষাত্কারের প্রসঙ্গেও আগ্রহী। উদাহরণস্বরূপ অনেকগুলি অ্যালগরিদম পাঠ্যপুস্তক (যেমন সিএলআর) সিউডোকোডে কোনও ত্রুটি পরীক্ষা না করেই অ্যালগরিদমগুলি উপস্থাপন করে। যাইহোক, যদিও এটি অ্যালগরিদমের মূল বোঝার জন্য ভাল এটি অবশ্যই কোনও ভাল প্রোগ্রামিং অনুশীলন নয়। সুতরাং আমি কোনও সাক্ষাত্কারকারীর কাছে বলতে চাই না যে আমি আমার কোড উদাহরণগুলি সহজ করার জন্য (পাঠ্যপুস্তক হিসাবে সম্ভবত) ত্রুটি পরীক্ষা করে এড়িয়ে যাচ্ছিলাম। তবে আমি অতিরিক্ত ত্রুটি পরীক্ষা করে অক্ষম কোড তৈরি করতে উপস্থিত হতে চাই না। উদাহরণস্বরূপ নালটি graph_get_current_column_colorযাচাই করার *graphজন্য এটি সংশোধন করা যেতে পারে তবে শূন্য হলে এটি কী করবে তা স্পষ্ট নয় *graph, অন্যটি এটির অবজ্ঞা না করা উচিত।


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


প্রশ্নটি এবং ২০১৩ সালে সর্বাধিক উত্তরগুলি লেখা ছিল মনে রেখে ২০১ the সালের এই অন্ধত্বের সাথে উত্তরগুলির কোনওটি কি সংযোজকগুলির অনুকূলকরণের কারণে সময়-ভ্রমণের অনির্ধারিত আচরণের বিষয়টি বিবেচনা করে ?
রয়ং

বৈধ পয়েন্টার আর্গুমেন্টের প্রত্যাশা করে এপিআই কলগুলির ক্ষেত্রে আমি ভাবছি যে কেবল নুলের জন্য পরীক্ষার মান কী? যে কোনও অবৈধ পয়েন্টার যা অবনমিত হয় সেগুলি NUL এর মতোই খারাপ হবে এবং সেগফল্ট সমস্ত একই।
PaulHK

উত্তর:


15

অবৈধ নাল পয়েন্টারগুলি হয় প্রোগ্রামার ত্রুটির কারণে বা রানটাইম ত্রুটির কারণে ঘটতে পারে। রানটাইম ত্রুটি এমন কিছু যা প্রোগ্রামার ঠিক করতে পারে না যেমন mallocকম মেমোরির কারণে ব্যর্থ হওয়া বা প্যাকেট ফেলে নেটওয়ার্ক বা ব্যবহারকারীকে বোকা কিছু enteringোকানো। প্রোগ্রামার ত্রুটিগুলি কোনও প্রোগ্রামার দ্বারা ভুলভাবে ফাংশনটি ব্যবহার করে are

আমি দেখেছি থাম্বের সাধারণ নিয়মটি হ'ল রানটাইম ত্রুটিগুলি সর্বদা পরীক্ষা করা উচিত তবে প্রোগ্রামার ত্রুটিগুলি প্রতিবার পরীক্ষা করা উচিত নয়। আসুন কিছু ইডিয়ট প্রোগ্রামারকে সরাসরি কল করা যাক graph_get_current_column_color(0)। এটি যখন প্রথমবার বলা হবে সেগফল্ট হবে তবে আপনি একবার এটি ঠিক করে ফেললে স্থায়ীভাবে স্থিরভাবে সংকলন করা হবে। এটি একবার চালানোর সময় চেক করার দরকার নেই।

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

স্পষ্টতই, আপনি সর্বদা আরও পেডেন্টিক কাউকে খুঁজে পেতে পারেন, তবে বেশিরভাগ সি প্রোগ্রামার আমি জানি যে কোডের তুলনায় কম বিশৃঙ্খল কোড যা প্রান্তিকভাবে নিরাপদ favor এবং "নিরাপদ" একটি বিষয়গত শব্দ। বিকাশের সময় একটি সুস্পষ্ট সেগফল্ট ক্ষেত্রের একটি সূক্ষ্ম দুর্নীতির ত্রুটির তুলনায় ভাল।


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

1
আইওএসে, malloc কখনই NULL ফেরত দেবে না। যদি এটি কোনও স্মৃতি খুঁজে না পায়, তবে এটি প্রথমে আপনার অ্যাপ্লিকেশনটিকে মেমরিটি মুক্তি দিতে বলবে, তারপরে এটি অপারেটিং সিস্টেমটিকে (যা অন্যান্য অ্যাপ্লিকেশনগুলিকে মেমরি প্রকাশ করতে এবং সম্ভবত তাদের হত্যা করতে বলবে) জিজ্ঞাসা করবে এবং যদি এখনও স্মৃতি না থাকে তবে এটি আপনার অ্যাপ্লিকেশনটিকে হত্যা করবে । কোন চেক প্রয়োজন।
gnasher729 12

11

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

তারা তাদের টার্মিনালগুলিতে "ঘটতে পারে না" দেখেছে এমন সংখ্যার দ্বারা দ্রুত নমনীয় হওয়ার কথা জানিয়েছেন।

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

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

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

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


8
আপনি যদি এমন কোনও ফাংশনে থাকেন যার জন্য একটি নন-নুল পয়েন্টার প্রয়োজন, তবে আপনি যেভাবেই চেক করেন এবং এটি নল ... এর পরে আর কী হবে?
অবধি

1
@ পরে আপনি যা করছেন তা বন্ধ করুন এবং একটি ত্রুটি কোডটি ফিরিয়ে দিন, বা একটি দৃsert়তার সাথে ভ্রমণ করুন
জেমস

1
@ জেমস - নিশ্চয়ই ভাবেন নি assert। আপনি যদি NULLচেক অন্তর্ভুক্ত করতে বিদ্যমান কোড পরিবর্তন করার কথা বলছেন তবে আমি ত্রুটি কোড ধারণাটি পছন্দ করি না ।
অবধি

10
@ তবে আপনি যদি ত্রুটি কোডগুলি পছন্দ না করেন তবে আপনি সি দেব হিসাবে খুব বেশি দূরে যাবেন না
জেমস

5
@ জনআর.স্ট্রোহম - এটি সি, এটি
জোর দেওয়া

5

আপনি যখন নিজেকে কোনওরকম বোঝাতে পারেন যে আপনি পয়েন্টারটি সম্ভবত নাল হতে পারে না তখন আপনি চেকটি এড়িয়ে যেতে পারেন।

সাধারণত, নাল পয়েন্টার চেকগুলি কোডে প্রয়োগ করা হয় যেখানে নাল একটি সূচক হিসাবে প্রত্যাশিত যে কোনও বস্তু বর্তমানে উপলব্ধ নেই। নাল একটি সংযুক্ত তালিকা, বা পয়েন্টার এমনকি অ্যারে বন্ধ করতে উদাহরণস্বরূপ, একটি সেন্ডিনেল মান হিসাবে ব্যবহৃত হয়। argvমধ্যে পাস স্ট্রিং ভেক্টর mainএকটি পয়েন্টার হতে প্রয়োজন বোধ করা হয় নাল-সমাপ্ত, একভাবে কিভাবে স্ট্রিং একটি নাল অক্ষর দ্বারা সমাপ্ত হয়: argv[argc]একটি নাল পয়েন্টার, এবং আপনি যখন কমান্ড লাইন পার্স এই নির্ভর করতে পারেন।

while (*argv) {
   /* process argument string *argv */
   argv++; /* increment to next one */
}

সুতরাং, নাল পরীক্ষা করার জন্য পরিস্থিতিগুলি সেগুলির মধ্যে এটির একটি প্রত্যাশিত মান। নাল চেকগুলি নাল পয়েন্টারের অর্থ বাস্তবায়িত করে যেমন কোনও লিঙ্কযুক্ত তালিকার সন্ধান বন্ধ করে দেওয়া। তারা কোডটিকে পয়েন্টারকে অবজ্ঞা করা থেকে বিরত রাখে।

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

একটি ডেটা ধরণের সম্পর্কে যেমন graph *: এটি এমনভাবে নকশা করা যেতে পারে যাতে নাল মানটি একটি বৈধ গ্রাফ: কোনও প্রান্ত এবং কোনও নোড না থাকা something এই ক্ষেত্রে, graph *পয়েন্টার গ্রহণকারী সমস্ত ক্রিয়াকলাপগুলিকে সেই মানটি মোকাবেলা করতে হবে, কারণ এটি গ্রাফের উপস্থাপনায় সঠিক ডোমেন মান। অন্যদিকে, একটি graph *ধারক-জাতীয় বস্তুর পয়েন্টার হতে পারে যা আমরা কোনও গ্রাফ ধরে রাখলে কখনই বাতিল হয় না; এরপরে একটি নাল পয়েন্টারটি আমাদের বলতে পারে যে "গ্রাফ অবজেক্টটি উপস্থিত নেই; আমরা এখনও এটি বরাদ্দ করি নি, বা আমরা এটিকে মুক্তি দিয়েছি; বা এর বর্তমানে কোনও সম্পর্কিত গ্রাফ নেই"। পয়েন্টারগুলির এই পরবর্তী ব্যবহারটি একটি সম্মিলিত বুলিয়ান / উপগ্রহ: পয়েন্টারটি নন-নাল হওয়া ইঙ্গিত দেয় "আমার এই বোন অবজেক্টটি আছে", এবং এটি সেই অবজেক্টটি সরবরাহ করে।

আমরা কোনও বস্তুকে অন্যের থেকে পৃথক করার জন্য কেবল কোনও বস্তু মুক্ত না করলেও আমরা নালার দিকে একটি পয়েন্টার সেট করতে পারি:

tty_driver->tty = NULL; /* detach low level driver from the tty device */

সবচেয়ে দৃinc়প্রত্যয়ী যুক্তি আমি জানি যে একটি নির্দিষ্ট বিন্দুতে কোনও পয়েন্টারটি বাতিল হতে পারে না সেটি হল "যদি (পিটিআর! = এনএলএল)" "এবং একটি অনুরূপ" rap "এ মোড়ানো হয়। এর বাইরে, আপনি আনুষ্ঠানিক যাচাইকরণ অঞ্চলে in
জন আর স্ট্রোহম

4

আমাকে ফাগুতে আরও একটি ভয়েস যুক্ত করুন।

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

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

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

এটা আমার দুই সেন্ট।


1

আমি সাধারণত যখন কেবলমাত্র কোনও পয়েন্টার নির্ধারিত হয় তখন তা যাচাই করি, যা কেবলমাত্র তখনই আমি আসলে এটি সম্পর্কে কিছু করতে পারি এবং এটি যদি অবৈধ হয় তবে সম্ভবত পুনরুদ্ধার করি।

উদাহরণস্বরূপ যদি আমি একটি উইন্ডোতে একটি হ্যান্ডেল পাই, আমি এটি নাল এবং ঠিক তখন এবং সেখানে আছে তা যাচাই করব এবং নাল অবস্থা সম্পর্কে কিছু করব, তবে আমি এটি প্রতিবারই নাল হয়ে যাব কিনা তা যাচাই করব না to আমি পয়েন্টারটি ব্যবহার করি, প্রতিটি ফাংশনে পয়েন্টারটি পাস করা হয়, অন্যথায় আমার নকল ত্রুটি পরিচালনা করার কোডের পর্বত থাকে।

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


1

আমি বলব যে এটি নিম্নলিখিতগুলির উপর নির্ভর করে:

  1. সিপিইউ ব্যবহার কি সমালোচনা? NULL এর প্রতিটি পরীক্ষায় কিছুটা সময় লাগে।
  2. পয়েন্টারটি নুল কী কী প্রতিক্রিয়া? এটি কি কেবল আগের ফাংশনে ব্যবহৃত হয়েছিল? পয়েন্টারের মান পরিবর্তন করা যেতে পারে।
  3. সিস্টেমটি কি প্রাকৃতিক? অর্থ একটি কার্য পরিবর্তন হতে পারে এবং মান পরিবর্তন করতে পারে? কোনও আইএসআর এসে মান পরিবর্তন করতে পারে?
  4. কোডটি কতটা শক্তভাবে মিলিত হয়?
  5. এমন কোনও স্বয়ংক্রিয় প্রক্রিয়া আছে যা নুল পয়েন্টারগুলি স্বয়ংক্রিয়ভাবে পরীক্ষা করবে?

সিপিইউ ইউটিলাইজেশন / অডস পয়েন্টারটি নুল হয় প্রতিবার আপনি যখন এনইউএলএল পরীক্ষা করেন তখন সময় লাগে। এই কারণে আমি আমার চেকগুলিকে সীমাবদ্ধ করার চেষ্টা করি যেখানে পয়েন্টারটির মান পরিবর্তন হতে পারে।

প্রিম্পিটিভ সিস্টেম যদি আপনার কোডটি চলমান থাকে এবং অন্য কোনও কাজ এটির মধ্যে বাধা সৃষ্টি করতে পারে এবং সম্ভাব্যভাবে মান পরিবর্তন করতে পারে তবে একটি চেক করা ভাল।

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

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

এটি উপলব্ধ কিনা পরীক্ষা করার জন্য একটি পয়েন্টার সহ একটি প্রোগ্রাম তৈরি করুন। পয়েন্টারটি 0 তে সেট করুন এবং তারপরে এটি পড়ার / লেখার চেষ্টা করুন।


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

1

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

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

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

void vertex_move(Vertex* v)
{
     if (!v)
          return;
     ...
}

... এবং কখনও কখনও ঠিক তেমনি একটি ত্রুটি কোডটিও ফেরত / সেট না করেই করা হয়। এবং এটি এমন একটি কোডবেসে ছিল যা বেশ কয়েক দশক পুর্বে বহু অর্জিত তৃতীয় পক্ষের প্লাগইন সহ with এটি অনেকগুলি বাগের সাথে জর্জরিত একটি কোডবেসও ছিল এবং প্রায়শই সমস্যাগুলির তাত্ক্ষণিক উত্স থেকে সরানো সাইটগুলিতে ক্র্যাশ হওয়ার প্রবণতা থাকার কারণে মূল কারণগুলির সন্ধান করা খুব জটিল ছিল এমন বাগগুলি।

এবং এই অনুশীলনটি এর অন্যতম কারণ ছিল। move_vertexএটিতে একটি শূন্য প্রান্তটি পাস করার জন্য এটি উপরের ফাংশনের একটি প্রতিষ্ঠিত প্রাক শর্ত লঙ্ঘন , তবুও এই জাতীয় ক্রিয়াকলাপটি নিঃশব্দে এটিকে গ্রহণ করেছে এবং প্রতিক্রিয়া হিসাবে কিছুই করেনি। সুতরাং যা হওয়ার প্রবণতা ছিল তা হ'ল একটি প্লাগইনটিতে একটি প্রোগ্রামার ভুল থাকতে পারে যার কারণে এটি ফাংশনটি শূন্য হয়ে যায়, কেবল এটি সনাক্ত না করে কেবল পরে অনেক কিছু করা যায় এবং অবশেষে সিস্টেমটি flaking বা ক্রাশ শুরু করে।

তবে এখানে আসল সমস্যাটি হ'ল সহজেই এই সমস্যাটি সনাক্ত করতে অক্ষম। সুতরাং আমি একবার দেখার চেষ্টা করেছি যে যদি আমি অ্যানালজিকাল কোডটিকে উপরে assert, এমনভাবে পরিণত করি তবে কী হবে :

void vertex_move(Vertex* v)
{
     assert(v && "Vertex should never be null!");
     ...
}

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

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

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


0

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


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

@ mh01 আপনি যদি কেবল এলোমেলো কোড ভাঙাচ্ছেন (যেমন অনুমান করা এবং ডকুমেন্টেশন না পড়া), তবে আমি ভাবি না যে অতিরিক্ত NULLচেকগুলি আরও বেশি কিছু করতে চলেছে। এটি সম্পর্কে চিন্তা করুন: এখন B()পরীক্ষা করে NULLএবং ... কি করে? ফিরবেন -1? যদি কলার চেক না করে তবে আপনার NULLকী আস্থা থাকতে পারে যে তারা যে -1কোনও উপায়ে রিটার্ন ভ্যালু কেস নিয়ে কাজ করবে ?
অবধি

1
আহ্বানকারীদের দায়িত্ব। আপনি নিজের দায়বদ্ধতার সাথে ডিল করেন, যার মধ্যে আপনার দেওয়া স্বেচ্ছাচারী / অজ্ঞাত / সম্ভাব্য-যাচাই করা ইনপুটগুলিতে বিশ্বাস না করা অন্তর্ভুক্ত। অন্যথায় আপনি কপ-আউট শহরে। যদি কলকারী চেক না করে তবে কলার ত্রুটি করেছে; আপনি যাচাই করেছেন, আপনার নিজের গাধা coveredাকা আছে, আপনি কলার যাকে লিখেছেন তা বলতে পারেন যে অন্তত আপনি কাজটি ঠিক করেছেন।
ম্যাক্সিমাস মিনিমাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.