c++ - অবজ - সি++ বই




মুছে যাওয়া পয়েন্টারটির সাথে ভিজ্যুয়াল স্টুডিও কী করবে এবং কেন? (4)

আমি পড়ছি এমন একটি সি ++ বইতে বলা হয়েছে যে যখন পয়েন্টারটি মুছে ফেলা হয় delete অপারেটরটি ব্যবহার করে অবস্থানটিতে মেমরিটি এটি নির্দেশ করা হয় "মুক্ত" হয় এবং এটি ওভাররাইট করা যায় can এটি আরও উল্লেখ করে যে পয়েন্টারটি একই স্থানে নির্দেশ দেওয়া অবিরত করবে যতক্ষণ না এটি পুনরায় সাইন করা হয় বা NULL সেট না করা হয়।

ভিজ্যুয়াল স্টুডিও 2012 তে; ব্যাপারটা মনে হয় না!

উদাহরণ:

#include <iostream>

using namespace std;

int main()
{
    int* ptr = new int;
    cout << "ptr = " << ptr << endl;
    delete ptr;
    cout << "ptr = " << ptr << endl;

    system("pause");

    return 0;
}

আমি যখন এই প্রোগ্রামটি সংকলন এবং চালনা করি তখন আমি নিম্নলিখিত আউটপুটটি পাই:

ptr = 0050BC10
ptr = 00008123
Press any key to continue....

পরিষ্কারভাবে মুছে ফেলা হবে এমন ঠিকানাটি পরিবর্তনের দিকে ইঙ্গিত করছে!

এটি কেন ঘটছে? বিশেষত ভিজ্যুয়াল স্টুডিওর সাথে এর কিছু যুক্ত রয়েছে?

এবং যদি মুছুন এটি যেভাবেই ইঙ্গিত করছে ঠিকানাটি পরিবর্তন করতে পারে, তবে কেন কিছু এলোমেলো ঠিকানার পরিবর্তে স্বয়ংক্রিয়ভাবে পয়েন্টারটিকে NULL সেট করবে না?


এটি আরও উল্লেখ করে যে পয়েন্টারটি একই স্থানে নির্দেশ দেওয়া অবিরত করবে যতক্ষণ না এটি পুনরায় সাইন করা হয় বা NULL এ সেট না করা হয়।

এটি অবশ্যই বিভ্রান্তিকর তথ্য।

পরিষ্কারভাবে মুছে ফেলা হবে এমন ঠিকানাটি পরিবর্তনের দিকে ইঙ্গিত করছে!

এটি কেন ঘটছে? বিশেষত ভিজ্যুয়াল স্টুডিওর সাথে এর কিছু যুক্ত রয়েছে?

এটি স্পষ্টভাবে ভাষা নির্দিষ্টকরণের মধ্যে রয়েছে। কল delete পরে ptr বৈধ নয়। ptr delete পরে ptr ব্যবহার করা ptr আচরণের কারণ। এটা করবেন না। রান টাইম এনভায়রনমেন্ট delete করার কল করার পরে ptr দিয়ে যা খুশি তা করতে মুক্ত।

এবং যদি মুছুন এটি যেভাবেই ইঙ্গিত করছে ঠিকানাটি পরিবর্তন করতে পারে, তবে কেন কিছু র্যান্ডম ঠিকানার পরিবর্তে পয়েন্টারটিকে স্বয়ংক্রিয়ভাবে NULL এ সেট করবে না কেন ???

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


আপনি /sdl সংকলন বিকল্পের পার্শ্ব প্রতিক্রিয়া দেখতে পাবেন। ভিএস ২০১৫ প্রকল্পের জন্য ডিফল্টরূপে চালু করা হয়েছে, এটি / জিএস সরবরাহ করে এর চেয়ে অতিরিক্ত সুরক্ষা চেক সক্ষম করে। প্রকল্প> বৈশিষ্ট্য> সি / সি ++> সাধারণ> এসডিএল এটিকে পরিবর্তন করতে সেটিংস পরীক্ষা করে।

এমএসডিএন নিবন্ধ থেকে উদ্ধৃতি:

  • সীমিত পয়েন্টার স্যানিটাইজেশন সম্পাদন করে। অভিব্যক্তিগুলিতে যা ডিरेফারেন্সগুলিতে জড়িত না এবং প্রকারভেদে কোনও ব্যবহারকারী-নির্ধারিত ডেস্ট্রাক্টর নেই, পয়েন্টার রেফারেন্সগুলি মুছার জন্য একটি কল করার পরে একটি অ-বৈধ ঠিকানায় সেট করা হয়। এটি বাসি পয়েন্টার রেফারেন্সগুলির পুনরায় ব্যবহার রোধ করতে সহায়তা করে।

মনে রাখবেন না যে আপনি যখন এমএসভিসি ব্যবহার করেন তখন NUL- এ মুছে ফেলা পয়েন্টার সেট করা একটি খারাপ অভ্যাস। এটি ডিবাগ হিপ এবং এই / এসডিএল বিকল্প উভয়ের কাছ থেকে পাওয়া সহায়তাকে পরাস্ত করে, আপনি আর আপনার প্রোগ্রামে অবৈধ ফ্রি / মুছুন কলগুলি সনাক্ত করতে পারবেন না।


আমি লক্ষ্য করেছি যে 00008123 সঞ্চিত ঠিকানাটি সর্বদা 00008123 দিয়ে ওভাররাইট করা হচ্ছে ...

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

... NULL এর জন্য চেকগুলি একটি সাধারণ কোড কনস্ট্রাক্ট যার অর্থ একটি স্যানিটাইজেশন মান হিসাবে NULL ব্যবহারের সাথে NUL এর বিদ্যমান চেকটি নিখরচায় একটি আসল মেমরির সুরক্ষা ইস্যুটি গোপন করতে পারে যার মূল কারণটি সত্যই সম্বোধনের প্রয়োজন।

এই কারণে আমরা 0x8123 কে স্যানিটাইজেশন মান হিসাবে বেছে নিয়েছি - অপারেটিং সিস্টেমের দৃষ্টিকোণ থেকে এটি শূন্য ঠিকানা (NULL) এর সমান মেমরি পৃষ্ঠায় রয়েছে তবে 0x8123 এ অ্যাক্সেস লঙ্ঘনটি বিকাশকারীকে আরও বিশদ মনোযোগের প্রয়োজন হিসাবে আরও ভালভাবে দাঁড়াবে detailed ।

এটি মুছে ফেলার পরে ভিজ্যুয়াল স্টুডিও পয়েন্টারটির সাথে কী করে তা কেবল তাই ব্যাখ্যা করে না, তারা কেন এটি স্বয়ংক্রিয়ভাবে NULL সেট না করা বেছে নিয়েছে তাও উত্তর দেয়!

এই "বৈশিষ্ট্য "টি" এসডিএল চেকস "সেটিংসের অংশ হিসাবে সক্ষম হয়েছে। এটি সক্ষম / অক্ষম করতে এখানে যান: প্রকল্প -> বৈশিষ্ট্য -> কনফিগারেশন বৈশিষ্ট্য -> সি / সি ++ -> সাধারণ -> এসডিএল চেক

এটি নিশ্চিত করতে:

এই সেটিংটি পরিবর্তন করা এবং একই কোডটি পুনরায় চালু করা নিম্নলিখিত আউটপুট উত্পাদন করে:

ptr = 007CBC10
ptr = 007CBC10

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

ভিজ্যুয়াল স্টুডিওর ডিজাইনে এই ত্রুটিটি নথিভুক্ত না করে আপনাকে একটি স্টিকি পরিস্থিতি তৈরি করতে পারে।


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

আর একটি বিষয় হ'ল, কিছু রান টাইম অপ্টিমাইজার সেই মানটি পরীক্ষা করতে পারে এবং এর ফলাফলগুলি পরিবর্তন করতে পারে।

পূর্ববর্তী সময়ে এমএস 0xcfffffff এ মান সেট করে।






delete-operator