যাইহোক, GDB ব্যবহার করার সময়, আপনি 'ত্রুটি: GDB ঠিকানায় মেমরি অ্যাক্সেস করতে পারে না' ত্রুটির সম্মুখীন হতে পারেন। এই ত্রুটি বিভ্রান্তিকর হতে পারে এবং ডিবাগিং রাখা কঠিন করে তোলে। এই নিবন্ধটি কেন এই ত্রুটিটি ঘটছে তা সনাক্ত করার উপর দৃষ্টি নিবদ্ধ করা হয়েছে এবং কোডের কিছু উদাহরণ দেখার উপর দৃষ্টি নিবদ্ধ করা হয়েছে যা আমাদের বুঝতে সাহায্য করে কিভাবে এই ত্রুটিটি সমাধান করা যায়।
উদাহরণ 1:
আসুন আমাদের প্রথম কোডের উদাহরণ দেখি যেটি কার্যকর করার সময়, 'Address এ GDB মেমরি অ্যাক্সেস করতে পারে না' ত্রুটি দেয়। প্রথমত, আমরা কোডটি দেখি। তারপর, আমরা এর লাইন-বাই-লাইন ব্যাখ্যা দেখতে পাব।
#অন্তর্ভুক্ত করুন
ব্যবহার নামস্থান std ;
int প্রধান ( অকার্যকর ) {
int * পি ;
cout << * পি ;
}
প্রোগ্রামটি শুরু হয় '#include
প্রধান ফাংশনের মধ্যে, '*p' পয়েন্টার ভেরিয়েবল ঘোষণা করা হয়। এখানে, 'p' ভেরিয়েবলটি আরম্ভ করা হয়নি। সুতরাং, এটি পূর্ণসংখ্যার জন্য সংরক্ষিত কোনো নির্দিষ্ট মেমরি অবস্থান নির্দেশ করে না। এই লাইনটি একটি ত্রুটি সৃষ্টি করে যা আমরা পরে সমাধান করব। পরের লাইনে, আমরা “cout” স্টেটমেন্ট ব্যবহার করে “*p” ভেরিয়েবলের মান প্রিন্ট করার চেষ্টা করি।
যেহেতু 'p' ভেরিয়েবল টাইপ পূর্ণসংখ্যার একটি পয়েন্টার, তাই তারকাচিহ্ন '*' এটিকে ডিরেফারেন্স করতে ব্যবহৃত হয়। এর মানে হল যে মানটি মেমরির অবস্থানে রয়েছে যা এটি নির্দেশ করে। যাইহোক, যেহেতু 'p' পয়েন্টারটি আরম্ভ করা হয়নি এবং কোনো নির্দিষ্ট এবং বৈধ অবস্থান নির্দেশ করে না, তাই পয়েন্টারটিকে ডিরেফারেন্স করার ফলে অনির্ধারিত আচরণ হবে। সুতরাং, এটি সিস্টেম এবং কম্পাইলারের উপর নির্ভর করে বিভিন্ন ধরণের ত্রুটি তৈরি করে। যেহেতু আমরা এই প্রোগ্রামটি ডিবাগ এবং চালানোর জন্য GDB কম্পাইলার ব্যবহার করছি, ডিবাগার নিম্নলিখিত ত্রুটিটি নিক্ষেপ করবে। ত্রুটিটি আউটপুট স্নিপেটে দেখানো হয়েছে:
আপনি আউটপুটে দেখতে পাচ্ছেন, ডিবাগার মেমরি অ্যাক্সেস করতে পারে না। এই প্রোগ্রামটি একটি অপ্রচলিত পয়েন্টারকে ডিরেফারেন্স করে, এই অনির্ধারিত আচরণের প্রধান কারণ। এখন দেখা যাক কিভাবে আমরা এই সমস্যার সমাধান করতে পারি। সঠিক কোড নিম্নলিখিত দেওয়া হয়. এটি একবার দেখুন এবং আমরা ব্যাখ্যা করব কিভাবে আমরা কোডের বাগটি ঠিক করব:
#অন্তর্ভুক্ত করুন
ব্যবহার নামস্থান std ;
int প্রধান ( অকার্যকর ) {
int ভাল = 5 ;
int * পি = এবং ভাল ;
cout << 'মান হল = ' << * পি ;
}
আপনি দেখতে পাচ্ছেন, কোডটি 'int val =5;' অন্তর্ভুক্ত করে পরিবর্তন করা হয়েছে। বিবৃতি এই লাইনটি 'val' নামে একটি পূর্ণসংখ্যা ভেরিয়েবল ঘোষণা করে এবং এটিকে '5' এর মান দিয়ে শুরু করে। পরবর্তী লাইন, 'int *p = &val;', একটি '*p' পয়েন্টার ভেরিয়েবল ঘোষণা করে এবং 'val' ভেরিয়েবলের ঠিকানা নির্দেশ করতে শুরু করা হয়। পূর্বে, '*p' পয়েন্টার কোনো মেমরি ঠিকানা নির্দেশ করে না যার কারণে '0x0 ঠিকানায় মেমরি অ্যাক্সেস করা যায় না'।
এই সমস্যাটি সমাধান করার জন্য, 'var' ভেরিয়েবলটি ঘোষণা করা হয়, আরম্ভ করা হয় এবং '*p' পয়েন্টারে বরাদ্দ করা হয়। এখন, “*p” পয়েন্টারটি “val” ভেরিয়েবলের ঠিকানা নির্দেশ করছে কারণ “&” অপারেটর “val”-এর ঠিকানা নেয় এবং “p”-এ বরাদ্দ করে। আবার, “cout” স্টেটমেন্ট ব্যবহার করা হয় “*p” পয়েন্টারের মান প্রিন্ট করতে। '*p' পয়েন্টার দ্বারা অ্যাক্সেস করা 'val' এর মান দেখতে নিম্নলিখিত আউটপুট স্নিপেটটি দেখুন:
আপনি লক্ষ্য করতে পারেন, ত্রুটিটি সমাধান করা হয়েছে এবং '5' এর মানটি আরম্ভ করা হয়েছে যেহেতু 'val' ভেরিয়েবলটি '*p' পয়েন্টার valribale কল করে প্রিন্ট করা হয়েছে।
উদাহরণ 2:
আসুন আমরা আরেকটি উদাহরণ বিবেচনা করি যা ব্যাখ্যা করে যে কিভাবে C++ কোড প্রোগ্রামে 'GDB মেমরি অ্যাট অ্যাকসেস করতে পারে না' ত্রুটি পূরণ করতে পারে। কোড আপনার রেফারেন্স জন্য নিম্নলিখিত দেওয়া হয়. একবার দেখুন:
# অন্তর্ভুক্ত করুনint প্রধান ( ) {
int * পি = নতুন int [ পনের ] ;
মুছে ফেলা [ ] পি ;
std :: cout << পি [ 2 ] << std :: endl ;
ফিরে 0 ;
}
পয়েন্টারগুলির সাথে প্রোগ্রামিং করার সময় বিকাশকারীরা যে সবচেয়ে সাধারণ পরিস্থিতিগুলির মুখোমুখি হন তা হল ভুল বা অনুপযুক্ত মেমরি বরাদ্দ। যখনই একটি C++ প্রোগ্রামে একটি ভুল মেমরি বরাদ্দ এবং ডিললোকেশন ঘটে তখনই GDB এর ফলে ত্রুটি দেখা দেয়।
পূর্ববর্তী কোড উদাহরণ বিবেচনা করে, একটি '*p' পয়েন্টার একটি নতুন int দিয়ে শুরু করা হয়[15]। এই বিবৃতিটি নতুন অপারেটর ব্যবহার করে গতিশীলভাবে 15টি পূর্ণসংখ্যার একটি অ্যারে বরাদ্দ করে। '*p' পয়েন্টার ভেরিয়েবল অ্যারের মেমরি ঠিকানা সংরক্ষণ করে।
নিচের বিবৃতিতে, “delete[] p;,” বলে যে মেমরিটি ডিলিট[] কমান্ড ব্যবহার করে ডিলোকেট করা হয়েছে। ডিলিট[] কমান্ডটি '*p' পয়েন্টারের পূর্বে বরাদ্দ করা মেমরিকে ডিলকেট করে যার মানে অন্য সিস্টেমটি ব্যবহার করে পূর্বে বরাদ্দ করা মেমরি ব্লক আবার বরাদ্দ করতে পারে। যখন আমরা 'cout' স্টেটমেন্ট ব্যবহার করে '*p' ভেরিয়েবলের মান প্রিন্ট করার চেষ্টা করি, তখন আমরা নিম্নলিখিত আউটপুটে দেখা মেমরি অ্যাক্সেস ত্রুটিটি পাব:
এখানে মনে রাখতে হবে যে সঠিক ত্রুটি বার্তাটি আপনার GDB সংস্করণ এবং সিস্টেমের উপর নির্ভর করে কিছুটা আলাদা হতে পারে। কিন্তু 'ত্রুটি: GDB অবস্থানে মেমরি অ্যাক্সেস করতে পারে না' এবং পূর্ববর্তী স্নিপেটে প্রদত্ত ত্রুটি একই। এই ত্রুটিটি সমাধান করার জন্য, আমরা কেবল 'cout' বিবৃতির পরে delete[] কমান্ডটি স্থানান্তর করি। নিম্নলিখিত সংশোধিত কোড দেখুন:
# অন্তর্ভুক্ত করুনint প্রধান ( ) {
int * পি = নতুন int [ পনের ] ;
জন্য ( int i = 0 ; i < পনের ; ++ i ) {
পি [ i ] = i * 2 - 5 + 8 ;
std :: cout << 'p[' << i << '] = ' << পি [ i ] << std :: endl ;
}
মুছে ফেলা [ ] পি ;
ফিরে 0 ;
}
এখানে, আপনি দেখতে পাচ্ছেন যে আমরা রান টাইমে গণনা করা মানগুলির সাথে অ্যারে শুরু করেছি এবং আমরা 'for' লুপ ব্যবহার করে লুপের সমস্ত মান প্রিন্ট করি। এখানে উল্লেখ্য সবচেয়ে গুরুত্বপূর্ণ বিষয় হল মুছে ফেলা [] স্টেটমেন্টের স্থানান্তর; এটি এখন অ্যারের সমস্ত মান পাওয়ার পরে বলা হয় যা মেমরি অ্যাক্সেস ত্রুটি সরিয়ে দিয়েছে। নিম্নলিখিত কোডের চূড়ান্ত আউটপুট দেখুন:
উপসংহার
উপসংহারে, 'ত্রুটি: GDB ঠিকানায় মেমরি অ্যাক্সেস করতে পারে না' ত্রুটি সাধারণত C++ কোডে মেমরি-সম্পর্কিত সমস্যাগুলি নির্দেশ করে। এই নিবন্ধটি কিছু সাধারণ পরিস্থিতির অন্বেষণ করেছে যা কখন এবং কীভাবে এটি সমাধান করা যেতে পারে তা ব্যাখ্যা করতে এই ত্রুটিটি শুরু করে। কোডে যখন এই ত্রুটিটি ঘটে, তখন পয়েন্টার ভেরিয়েবল, মেমরি বরাদ্দ, অ্যারে এবং কাঠামোর প্রতি গভীর মনোযোগ দিয়ে এটিকে সাবধানে পর্যালোচনা করা অপরিহার্য।
অধিকন্তু, GDB দ্বারা উপলব্ধ ব্রেকপয়েন্টের মতো বৈশিষ্ট্যগুলি প্রোগ্রামটি ডিবাগ করার সময় ত্রুটি সনাক্ত করতে সহায়তা করতে পারে। এই বৈশিষ্ট্যগুলি মেমরি-সম্পর্কিত ত্রুটিগুলির সঠিক অবস্থান চিহ্নিত করতে সাহায্য করতে পারে। এই সমস্যাগুলিকে সক্রিয়ভাবে সমাধান করার মাধ্যমে, বিকাশকারীরা তাদের C++ অ্যাপ্লিকেশনগুলির স্থায়িত্ব এবং নির্ভরযোগ্যতা বাড়াতে পারে।