সেগমেন্টেশন দোষ কী? এটি কি সি এবং সি ++ এ আলাদা? বিভাজন ত্রুটি এবং ঝুঁকিপূর্ণ পয়েন্টারগুলি কীভাবে সম্পর্কিত?
NullPointerException
।
সেগমেন্টেশন দোষ কী? এটি কি সি এবং সি ++ এ আলাদা? বিভাজন ত্রুটি এবং ঝুঁকিপূর্ণ পয়েন্টারগুলি কীভাবে সম্পর্কিত?
NullPointerException
।
উত্তর:
বিভাগের ত্রুটি একটি নির্দিষ্ট ধরণের ত্রুটি যা মেমরি অ্যাক্সেসের কারণে ঘটে যা "আপনার নিজের নয়।" এটি একটি সহায়ক প্রক্রিয়া যা আপনাকে মেমরিটিকে দূষিত করা এবং হার্ড-টু-ডিবাগ মেমরি বাগগুলি প্রবর্তন থেকে বিরত রাখে। আপনি যখনই কোনও সেগফোল্ট পেয়েছেন তখনই আপনি জানেন যে আপনি মেমরির সাথে কিছু ভুল করছেন - ইতিমধ্যে মুক্ত হওয়া ভেরিয়েবলটি অ্যাক্সেস করা, মেমরির কেবল পঠনযোগ্য অংশে লেখা ইত্যাদি Se মেমরি পরিচালনা, সি এবং সি ++ এর সেগফাল্টগুলির মধ্যে কোনও মূল পার্থক্য নেই।
সিগফল্ট পাওয়ার অনেকগুলি উপায় রয়েছে, কমপক্ষে নিম্ন স্তরের ভাষায় যেমন সি (++) তে। সেগফোল্ট পাওয়ার একটি সাধারণ উপায় হ'ল নাল পয়েন্টারকে অবজ্ঞা করা:
int *p = NULL;
*p = 1;
আপনি মেমরির এমন একটি অংশে লেখার চেষ্টা করবেন যা কেবল পঠনযোগ্য হিসাবে চিহ্নিত হয়েছে:
char *str = "Foo"; // Compiler marks the constant string as read-only
*str = 'b'; // Which means this is illegal and results in a segfault
ঝাঁকুনি পয়েন্টার এমন একটি জিনিসের দিকে ইঙ্গিত করে যা এখানে আর অস্তিত্ব রাখে না:
char *p = NULL;
{
char c;
p = &c;
}
// Now p is dangling
পয়েন্টারটি p
dangles কারণ এটি অক্ষর ভেরিয়েবলের দিকে ইঙ্গিত করে c
যা ব্লকটি শেষ হওয়ার পরে অস্তিত্বই বন্ধ হয়ে যায়। এবং যখন আপনি ঝুঁকির পয়েন্টারকে (যেমন *p='A'
) ডিফারেন্স করার চেষ্টা করবেন , আপনি সম্ভবত একটি সেগফল্ট পাবেন।
c
এটি স্থানীয়, এর অর্থ হল এটি স্ট্যাকের পরে চাপানো হয়েছে {
এবং এটির পরে পপ-এড বেরিয়েছে }
। ঝুঁকিপূর্ণ পয়েন্টারটি কেবল অফসেটের একটি উল্লেখ যা এখন স্ট্যাকের বাইরে। এ কারণেই কোনও সাধারণ প্রোগ্রামে এটি পরিবর্তন করা কখনই কোনও সেগফল্টকে ট্রিগার করবে না। অন্যদিকে এটি আরও জটিল ব্যবহারের ক্ষেত্রে সেগফল্টের দিকে পরিচালিত করতে পারে, যেখানে অন্যান্য ফাংশন কলগুলি স্ট্যাকটি বাড়ার দিকে পরিচালিত করতে পারে এবং ঝুঁকির পয়েন্টার দ্বারা নির্দেশিত ডেটা থাকতে পারে।
SIGSEGV
এটির জন্য বিষয় হিসাবে তৈরি করে , তাই স্ট্যাকের সাথে ম্যাংলিং থেকে আমি এ জাতীয় সংকেত আশা করব না।
এটি লক্ষ্য করার মতো বিষয় যে সরাসরি বিভাগে দোষটি অন্য কোনও প্রক্রিয়া স্মৃতিতে অ্যাক্সেসের কারণে ঘটে না (এটি আমি কখনও কখনও শুনছি), কারণ এটি সহজভাবে সম্ভব নয়। ভার্চুয়াল মেমরির সাথে প্রতিটি প্রক্রিয়ার নিজস্ব ভার্চুয়াল ঠিকানা স্থান রয়েছে এবং পয়েন্টারের কোনও মান ব্যবহার করে অন্য কোনওটিতে অ্যাক্সেস করার কোনও উপায় নেই। এর ব্যতিক্রমগুলি ভাগ করে নেওয়া লাইব্রেরিগুলি হতে পারে যা একই শারীরিক ঠিকানার স্পেস ম্যাপযুক্ত (সম্ভবত) বিভিন্ন ভার্চুয়াল ঠিকানা এবং কার্নেল মেমরি যা প্রতিটি প্রক্রিয়াতে একইভাবে ম্যাপ করা হয় (সিস্টেলে টিএলবি ফ্লাশিং এড়াতে, আমি মনে করি)। এবং shmat;) এর মতো জিনিস - এগুলি আমি 'অপ্রত্যক্ষ' অ্যাক্সেস হিসাবে গণ্য করি। তবে যে কেউ তা পরীক্ষা করে দেখতে পারেন যে তারা সাধারণত প্রক্রিয়া কোড থেকে অনেক দূরে অবস্থিত এবং আমরা সাধারণত তাদের অ্যাক্সেস করতে সক্ষম হয়েছি (এ কারণেই তারা সেখানে রয়েছে,
তবুও, আমাদের নিজস্ব (প্রক্রিয়া) মেমোরিটিকে ভুল উপায়ে অ্যাক্সেস করার ক্ষেত্রে বিভাগের ত্রুটি ঘটতে পারে (উদাহরণস্বরূপ, লিখনযোগ্য স্থানে লেখার চেষ্টা করা)। তবে এর সর্বাধিক সাধারণ কারণ হ'ল ভার্চুয়াল অ্যাড্রেস স্পেসের অংশটি অ্যাক্সেস যা শারীরিকভাবে কোনওটিতে ম্যাপ করা হয়নি ।
এবং ভার্চুয়াল মেমরি সিস্টেমের সাথে এই সমস্ত।
বিভাগটির ত্রুটি এমন কোনও পৃষ্ঠার অনুরোধের কারণে ঘটে থাকে যা প্রক্রিয়াটি তার বর্ণনাকারী সারণীতে তালিকাভুক্ত না করে বা এটি তালিকাভুক্ত কোন পৃষ্ঠাটির জন্য একটি অবৈধ অনুরোধ (যেমন কেবল পঠনযোগ্য পৃষ্ঠায় একটি লিখিত অনুরোধ)।
ড্যাংলিং পয়েন্টারটি এমন পয়েন্টার যা কোনও বৈধ পৃষ্ঠায় নির্দেশ করতে পারে বা নাও পারে, তবে স্মৃতির "অপ্রত্যাশিত" বিভাগকে নির্দেশ করে।
সত্যি কথা বলতে, অন্যান্য পোস্টারগুলি যেমন উল্লেখ করেছে, উইকিপিডিয়ায় এটির একটি খুব ভাল নিবন্ধ রয়েছে তাই এখানে একবার দেখুন। এই ধরণের ত্রুটি খুব সাধারণ এবং প্রায়শই অন্যান্য জিনিস যেমন অ্যাক্সেস লঙ্ঘন বা সাধারণ সুরক্ষা ফল্ট হিসাবে ডাকা হয়।
এগুলি সি, সি ++ বা অন্য কোনও ভাষায় আলাদা নয় যা পয়েন্টারগুলিকে অনুমতি দেয়। এই ধরণের ত্রুটিগুলি সাধারণত পয়েন্টারগুলির কারণে হয়
উইকিপিডিয়া অনুসারে:
বিভাগটি ত্রুটি ঘটে যখন কোনও প্রোগ্রাম কোনও মেমোরি অবস্থান অ্যাক্সেস করার চেষ্টা করে যা এটি অ্যাক্সেস করার অনুমতি নেই, বা মেমরির অবস্থানটিতে এমনভাবে প্রবেশ করার চেষ্টা করে যা অনুমোদিত নয় (উদাহরণস্বরূপ, কেবলমাত্র পঠনযোগ্য স্থানে লেখার চেষ্টা করা, বা অপারেটিং সিস্টেমের অংশটি ওভাররাইট করতে)।
বিভাগের ত্রুটিটি হার্ডওয়্যার ব্যর্থতার কারণেও ঘটে থাকে, এই ক্ষেত্রে র্যাম স্মৃতি। এটি হ'ল সাধারণ কারণ, তবে আপনি যদি আপনার কোডটিতে একটি ত্রুটি না খুঁজে পান, তবে কোনও স্মৃতিচিহ্ন আপনাকে সাহায্য করতে পারে।
এই ক্ষেত্রে সমাধান, র্যাম পরিবর্তন করুন।
সম্পাদনা:
এখানে একটি উল্লেখ রয়েছে: হার্ডওয়্যার দ্বারা বিভাজন ত্রুটি
বিভাগ যখন ত্রুটি ঘটে তখন কোনও প্রক্রিয়া (কোনও প্রোগ্রামের চলমান উদাহরণ) কেবলমাত্র পঠনযোগ্য মেমরি ঠিকানা বা মেমরির পরিসর যা অন্য প্রক্রিয়া দ্বারা ব্যবহৃত হয় বা অস্তিত্বহীন (অবৈধ) মেমরি ঠিকানাটিতে অ্যাক্সেস করার চেষ্টা করে। ড্যাংলিং রেফারেন্স (পয়েন্টার) সমস্যার অর্থ হ'ল এমন কোনও বস্তু বা ভেরিয়েবল অ্যাক্সেস করার চেষ্টা করা যার বিষয়বস্তু ইতিমধ্যে মেমরি থেকে মুছে ফেলা হয়েছে, যেমন:
int *arr = new int[20];
delete arr;
cout<<arr[1]; //dangling problem occurs here
উইকিপিডিয়ায় সেগমেন্টেশন_ফল্ট পৃষ্ঠাটিতে এটি সম্পর্কে খুব সুন্দর বর্ণনা রয়েছে, কেবল কারণগুলি এবং কারণগুলি নির্দেশ করে। বিস্তারিত বিবরণের জন্য উইকিতে দেখুন।
কম্পিউটিংয়ে, একটি সেগমেন্টেশন ত্রুটি (প্রায়শই সেগফল্টকে ছোট করা হয়) বা অ্যাক্সেস লঙ্ঘন একটি মেমরি অ্যাক্সেস লঙ্ঘন সম্পর্কে কোনও অপারেটিং সিস্টেম (ওএস) কে অবহিত করে মেমরি সুরক্ষা সহ হার্ডওয়্যার দ্বারা উত্থাপিত একটি দোষ।
নীচে বিভাগগুলির ত্রুটির কয়েকটি সাধারণ কারণ রয়েছে:
এগুলি প্রায়শই প্রোগ্রামিং ত্রুটির কারণে ঘটে থাকে যার ফলে অবৈধ মেমরি অ্যাক্সেস হয়:
নির্বিঘ্নিত বিন্দু বিন্দু নির্ধারণ বা বরাদ্দকরণ (বন্য পয়েন্টার, যা একটি এলোমেলো স্মৃতি ঠিকানার দিকে নির্দেশ করে)
একটি মুক্ত পয়েন্টারকে ডিফারেন্সিং বা বরাদ্দকরণ (ঝুলন্ত পয়েন্টার, যা মেমরিটিকে নির্দেশ করে যা মুক্ত / অবহেলিত / মুছে ফেলা হয়েছে)
একটি বাফার ওভারফ্লো।
একটি স্ট্যাক ওভারফ্লো
এমন কোনও প্রোগ্রাম কার্যকর করার চেষ্টা করা হচ্ছে যা সঠিকভাবে সংকলন করে না। (কিছু সংকলক সংকলন-সময় ত্রুটির উপস্থিতি সত্ত্বেও একটি এক্সিকিউটেবল ফাইল আউটপুট দেবে))
সহজ কথায়: বিভাগকে ত্রুটি হ'ল অপারেটিং সিস্টেমটি প্রোগ্রামটিতে একটি সিগন্যাল প্রেরণ করে যে এটি একটি অবৈধ মেমরির অ্যাক্সেস সনাক্ত করেছে এবং মেমরিটিকে দূষিত হওয়ার হাতছাড়া করতে অকাল থেকেই প্রোগ্রামটি বন্ধ করে দিচ্ছে।
"বিভাগকরণ ত্রুটি" এর অর্থ হল আপনি মেমোরিটি অ্যাক্সেস করার চেষ্টা করেছিলেন যা আপনার অ্যাক্সেস নেই।
প্রথম সমস্যাটি আপনার মূল তর্কগুলি নিয়ে। মূল ফাংশনটি হওয়া উচিত int main(int argc, char *argv[])
এবং আপনার argv অ্যাক্সেস করার আগে কমপক্ষে 2 টি পরীক্ষা করা উচিত [1]।
এছাড়াও, যেহেতু আপনি একটি ফ্লোটে প্রিন্টফের মধ্যে যাচ্ছেন (যা প্রিন্টফে যাওয়ার সময় ডাবল রূপান্তরিত হয়), আপনার% f ফর্ম্যাট স্পেসিফায়ার ব্যবহার করা উচিত। % S ফর্ম্যাট স্পেসিফায়ার স্ট্রিংগুলির জন্য ('\ 0'- সমাপ্ত অক্ষর অ্যারে)।
একটি বিভাগ যখন অস্তিত্বহীন মেমরির অবস্থানটি অ্যাক্সেস করার চেষ্টা করে বা মঞ্জুরিপ্রাপ্ত না হয় এমনভাবে কোনও মেমরির অবস্থান অ্যাক্সেস করার চেষ্টা করে তখন সেগমেন্টেশন ত্রুটি বা অ্যাক্সেস লঙ্ঘন ঘটে।
/* "Array out of bounds" error
valid indices for array foo
are 0, 1, ... 999 */
int foo[1000];
for (int i = 0; i <= 1000 ; i++)
foo[i] = i;
এখানে আমি [1000] উপস্থিত নেই, তাই সেগফল্ট ঘটে।
বিভাজন ত্রুটির কারণগুলি:
it arise primarily due to errors in use of pointers for virtual memory addressing, particularly illegal access.
De-referencing NULL pointers – this is special-cased by memory management hardware.
Attempting to access a nonexistent memory address (outside process’s address space).
Attempting to access memory the program does not have rights to (such as kernel structures in process context).
Attempting to write read-only memory (such as code segment).
উত্তরে "সেগমেন্টেশন ফল্ট" এর বেশ কয়েকটি ভাল ব্যাখ্যা রয়েছে, তবে যেহেতু সেগমেন্টেশন দোষের সাথে প্রায়শই মেমরির বিষয়বস্তু ডাম্প হয়, তাই আমি ভাগ করতে চেয়েছিলাম যেখানে সেগমেন্টেশন ফল্ট (কোর ডাম্পড) এর "কোর ডাম্পড" অংশের মধ্যে সম্পর্ক রয়েছে and স্মৃতি থেকে আসে:
প্রায় 1955 থেকে 1975 - অর্ধপরিবাহী মেমরির আগে - কম্পিউটার মেমরির প্রভাবশালী প্রযুক্তি তামার তারগুলিতে ক্ষুদ্র চৌম্বকীয় ডোনাট ব্যবহার করত। ডোনাটগুলি "ফেরাইট কোর" এবং প্রধান মেমরি হিসাবে পরিচিত যা "কোর মেমরি" বা "কোর" নামে পরিচিত।
সেগমেন্টেশন ত্রুটির যথেষ্ট সংজ্ঞা রয়েছে, আমি প্রোগ্রামিং করার সময় কয়েকটি উদাহরণ উদ্ধৃত করতে চাই, যা নির্বোধ ভুল বলে মনে হতে পারে তবে অনেক সময় নষ্ট করবে।
প্রিন্টেফের মধ্যে আরগুমেট টাইপ মিল না থাকলে আপনি নীচের ক্ষেত্রে সেগমেন্টেশন ত্রুটি পেতে পারেন
#include<stdio.h>
int main(){
int a = 5;
printf("%s",a);
return 0;
}
আউটপুট: Segmentation Fault (SIGSEGV)
আপনি যখন কোনও পয়েন্টারে মেমরি বরাদ্দ করতে ভুলে গিয়েছিলেন তবে এটি ব্যবহারের চেষ্টা করছেন।
#include<stdio.h>
typedef struct{
int a;
}myStruct;
int main(){
myStruct *s;
/* few lines of code */
s->a = 5;
return 0;
}
আউটপুট: Segmentation Fault (SIGSEGV)
এর সহজ অর্থ Segmentation fault
হ'ল আপনি এমন কিছু মেমোরি অ্যাক্সেস করার চেষ্টা করছেন যা আপনার নিজের নয়। Segmentation fault
যখন আমরা কেবলমাত্র পঠনযোগ্য মেমরির স্থানে কাজগুলি পড়তে এবং / অথবা লেখার চেষ্টা করি বা মেমরিটি মুক্ত করার চেষ্টা করি তখন ঘটে। অন্য কথায়, আমরা এটিকে এক ধরণের স্মৃতি দুর্নীতি হিসাবে ব্যাখ্যা করতে পারি।
নীচে আমি প্রোগ্রামারদের দ্বারা পরিচালিত সাধারণ ভুলগুলি উল্লেখ করি যা নেতৃত্ব দেয় Segmentation fault
।
scanf()
ভুল উপায়ে ব্যবহার (রাখা ভুলে গেছেন &
)।int num;
scanf("%d", num);// must use &num instead of num
int *num;
printf("%d",*num); //*num should be correct as num only
//Unless You can use *num but you have to point this pointer to valid memory address before accessing it.
char *str;
//Stored in read only part of data segment
str = "GfG";
//Problem: trying to modify read only memory
*(str+1) = 'n';
// allocating memory to num
int* num = malloc(8);
*num = 100;
// de-allocated the space allocated to num
free(num);
// num is already freed there for it cause segmentation fault
*num = 110;
printf()
এবং scanf()
' ব্যবহার করার সময় ভুল ফর্ম্যাট স্পেসিফায়ার ব্যবহার করুন