دانشجوی مهندسی کامپیوتر هستم و از یاد گرفتن مسائل طراحی الگوریتم لذت میبرم.
چه زمانی segmentation fault رخ میدهد؟
احتمالا براتون پیش اومده که داشتید راه میرفتید و حواستون به مسیر نبوده و یهو زیر پاتون خالی شده. یا داشتید از پله ها بالا میرفتید یهو پله ها تموم شده و یه شوک بهتون وارد شده باشه. یا اگه این اتفاق ها براتون نیوفتاده دیگه حتما پیش اومده یا دیدید که یکی وقتی میخواد بلند شه سرش به جایی بخوره و کلی مثال دیگه تو زندگی واقعی که میشه درموردش حرف زد.
مصداق همه اتفاقات بالا توی برنامه نویسی تو c و cpp میشه segmentation fault.
اصولا این خطا زمانی رخ میده که سیستم در زمان اجرا فکر می کنه که طبق حالت های روتین میتونه کاری رو انجام بده ولی عوامل بیرونی بهش شوک وارد میکنند و برنامه رو متوقف میکنند.
قبل از آشنایی این نوع خطا بهتره که یه پیش زمینه کوچیکی از اشارهگرها(Pointer) داشته باشیم. به طور کلی اشارهگر یه نوع داده است مثل بقیه نوع داده ها و مقادیری که ازش نگهداری میکنه، آدرس های حافظه هستند که اون نقطه از حافظه هرجایی میتونه باشه و محدودیتی نداره که همین گاهی سبب مشکلاتی میشه.
حالا بریم ببینیم کجا ها قراره با این خطا دیدار کنیم:
دسترسی به خارج محدوده آرایه(Array out of bound):
زمانی که آرایه تعریف میشه سیستم به اندازه فضایی که آرایه نیاز داره بهش فضا اختصاص داده میشه. و سیستم فقط آدرس خونه اول آرایه رو نگه میداره و هربار که توی کد به یکی از خونه های آرایه نیاز دارید، برنامه حاصل ضرب اندیس در میزان فضای مورد نیاز برای یک متغیر از جنس آرایه رو به آدرس خونه اول اضافه میکنه تا به اون خونه دسترسی داشته باشیم. حالا اگه ما یک آرایه به طول 5 داشته باشیم و اگه بخایم عنصر 10ام رو مقداردهی کنیم، امکان داره اون نقطه از حافظه در اختیار برنامه دیگه ای باشه و سیستم عامل به شما اجازه نده و برنامه بسته شه، البته این نکته قابل ذکره که گاهی شما میتونید خارج از محدوده آرایه تغییر ایجاد کنید ولی تضمین شده نیست.
مقداردهی به NULL:
باور غلطی که درمورد NULL وجود داره اینه که وقتی یه اشارهگر به NULL اشاره میکنه، یعنی به جایی اشاره نمیکنه درصورتی که NULL اسم یک نقطه ثابت (معمولا نقطه اول حافظه) در حافظه است که هیچ کس اجازه تغییر آن را ندارد. و در صورتی که برنامه بخواهد مقدار NULL را تغییر دهد دچار خطا میشه.
مقدار دهی به فضای آزاد شده:
زمانی که قسمتی از حافظه توسط برنامه آزاد میشه، برنامه دیگه اجازه مقداردهی به اون بخش رو نداره و مثالش رو میتونید ببینید.
تغییر در رشته(String):
همونطور که میدونید رشته یک نوع داده غیرقابل تغییره(Immutable data type) که برای تغییر دادنش باید یک رشته جدید ایجاد کنیم و نمیتونیم همون رشته در اون نقطه از حافظه رو تغییر بدیم. احتمالا مثال زیر برای درک موضوع بیشتر بهتون کمک میکنه.
سرریزکردن پشته (Stack overflow):
برخلاف موارد قبلی که مربوط به اشارهگر ها بود، این مورد به اشارهگر ها ربطی نداره. به هر برنامه بر شروع یک پشته اختصاص داده میشه که حافظه محدودی داره و به ازای هر تابعی که فراخوانی میشه اسم اون تابه به ابتدای پشته اضافه میشه و تا وقتی که از اون تابع بیرون بیایم. این خطا معمولا توی توابع بازگشتی رخ میده که با بررسی شرط پایان معمولا قابل حله.
استفاده نامناسب از تابع scanf:
بیاید این یه مورد رو از روی مثال بررسی کنیم. توی مثال زیر تابع scanf به آدرس یک متغیر را به عنوان ورودی نیاز داره. در اینجا در این برنامه n به تابع پاس داده میشود. مقدار n رو 2 و آدرسشو را 1000 در نظر بگیرید. اگر n را به scanf () منتقل کنیم ، ورودی به جای اینکه در حافظه 1000 بشینه، تو حافظه 2 میشینه که باعث خطا میشه.
توی این نوشته سعی کردم متداول ترین زمان هایی که segmentation fault رخ میده رو معرفی کنم. مواردی هستتن که ذکر نشدن ولی با درک نوع خطا میتونید به راحتی متوجه باقی خطا ها بشید.
امیدوارم این مطلب به شما کمک کنه.
موفق باشید.
مطلبی دیگر از این انتشارات
چگونه در پایتون کد هایمان را تست کنیم؟
مطلبی دیگر از این انتشارات
تفاوت برنامه نویسی و مهندس نرم افزار
مطلبی دیگر از این انتشارات
سورس برنامه رمزنگاری و رمزگشایی فایل به زبان پایتون