מצביע האפס

במחשוב, מצביע האפס (באנגלית: Null pointer) הוא ערך שמור כדי לציין שמצביע מתייחס לאובייקט לא חוקי. תוכניות משתמשות באופן שגרתי במצביע אפס כדי לייצג תנאים מסוימים כגון סוף רשימה או לייצוג כישלון בפעולה כלשהי האמורה להציב ערך למצביע. ניתן להשוות את מצביע האפס לערך "Nothing" המופיע במספר שפות תכנות.

מצביע אפס אינו מצביע שאינו מאותחל . עבור מצביע אפס, מובטח שהוא שונה מכל מצביע אשר מצביע על אובייקט חוקי או על מקום תקף בזיכרון ולכן שימוש בו יוביל בהכרח לשגיאה. לעומת זאת, בשפות תכנות שונות מאפשרות להשתמש במצביע שאינו מאותחל, אך זה עלול לגרום להתנהגות בלתי צפויה .

בשפת C 
ב- C, מובטח ששני מצביעי אפס מכל סוג יהיו שווים. המאקרו NULL מוגדר כקבוע, וב- C99 ניתן לבטאו כ (0(void *)) - כלומר המרה של הערך 0 לסוג void* (מצביע לסוג void ). תקן C אינו קובע שמצביע האפס אמור להיות זהה לכתובת המצביע לכתובת 0, אם כי זה עשוי להיות המקרה בפועל. התייחסות למצביע אפס היא התנהגות לא מוגדרת ב-C.

בפועל, התייחסות למצביע null עלולה לגרום לניסיון קריאה או כתיבה מזיכרון שאינו ממופה, ולעורר שגיאת גישה לזיכרון, דבר העשוי לגרום לקריסת תוכנית, או להפוך לחריגת תוכנה הניתנת לטיפול על ידי קוד התוכנית. עם זאת, ישנן נסיבות מסוימות שבהן זה לא המקרה. לדוגמה, ב- x86, הכתובת 0000:0000 ניתנת לעיתים לקריאה או לכתיבה, והפניית מצביע לכתובת זו היא פעולה חוקית לחלוטין אך בדרך כלל לא רצויה שעלולה להוביל להתנהגות לא מוגדרת אך לא קורסת באפליקציה. ישנם מקרים שבהם הפניית המצביע לכתובת אפס היא מכוונת ומוגדרת היטב; לדוגמה, קוד BIOS שנכתב ב-C עבור התקני x86 של 16 סיביות עשוי לכתוב את טבלת הפסיקות בכתובת פיזית 0 של המכונה על ידי הפניה של מצביע null לכתיבה. אפשרות אחרת למימוש מהדר היא לבצע אופטימיזציה המניחה שאין בקוד התייחסות למצביע null, התנהגות העשויה לגרום להתנהגות לא צפויה במידה והקוד דווקא מכיל בטעות התייחסויות כאלו.

++C 
ב-++C, בעוד NULL עבר בירושה מ-C, המספר השלם של אפס הועדף באופן מסורתי כדי לייצג קבוע מצביע אפס. עם זאת, C++11 הציג את קבוע המצביע null המפורש nullptr לשימוש במקום זאת.

שפות אחרות 
בסביבות שפת תכנות מסוימות (לפחות מימוש קנייני אחד של Lisp, למשל), הערך המשמש כמצביע null (נקרא nil ב- Lisp ) עשוי להיות למעשה מצביע לגוש של נתונים פנימיים שימושיים ליישום (אך לא ניתן להגיע אליו במפורש מתוכניות משתמש), ובכך לאפשר שימוש באותו אוגר. כקבוע שימושי וכדרך מהירה לגישה למידע "פנימי" של היישום (הידוע כווקטור nil) .

שפות תכנות שונות משתמשות בטרמינולוגיה שונה עבור מצביע האפס . ב-Python, למשל, הערך קרוי None . בפסקל ובסוויפט, מצביע אפס נקרא nil . באייפל, void.

התייחסות למצביע האפס 
היות שמצביע האפס אינו מצביע על אובייקט בעל משמעות, ניסיון להתייחס למצביע ריק (כלומר, לגשת לנתונים המאוחסנים במיקום הזיכרון אליו מורה המצביע) בדרך כלל (אך לא תמיד) גורם לשגיאת זמן ריצה או קריסת תוכנית מיידית.
 ב-C, התייחסות למצביע אפס היא התנהגות לא מוגדרת. יישומים רבים גורמים לקוד כזה לגרום לעצירת התוכנית, מכיוון שייצוג המצביע null נבחר להיות כתובת שלעולם לא מוקצית על ידי המערכת לאחסון אובייקטים. עם זאת, התנהגות זו אינה אוניברסלית וגם אינה מובטחת, שכן מהדרים רשאים לבצע אופטימיזציה של תוכניות בהנחה שהם נקיים מהתנהגות לא מוגדרת.
 ב-Delphi ובמימושים אחרים של Pascal, הקבוע nil מייצג מצביע לכתובת הראשונה בזיכרון המשמשת גם לאתחול משתנים. התייחסות אליו תגרום לחריגת מערכת הפעלה.
 ב-Java, התייחסות ל- null מפעילה NullPointerException (NPE), אשר ניתנת לטיפול על ידי קוד טיפול בשגיאות, אך הנוהג המועדף הוא לנסות להבטיח שחריגים כאלה לעולם לא יתרחשו.
 ב-, גישה ל- null גורמת ל-NullReferenceException. טיפול בה אינו מומלץ אך אפשרי.
 ב-Objective-C, הודעות עשויות להישלח לאובייקט nil (שהוא מצביע null) מבלי לגרום להפרעה לתוכנית. התכנית מתעלמת מההודעה, וערך ההחזרה (אם ישנו) הוא nil או 0, תלוי בסוג.
 לפני ההשקה של SMAP, ניתן היה לנצל באג של הפניית מצביע null על ידי מיפוי pagezero לתוך מרחב הכתובות של התוקף, ומכאן לגרום למצביע null להצביע לאזור זה, מה שעלול להוביל לביצוע קוד זדוני במקרים מסוימים.

טיפול בבאגים 
ישנן טכניקות כדי להקל על ניפוי באגים הנגרמים מהתייחסות למצביע אפס. הוצע לשנות את JVM כדי לעקוב אחר התפשטות של ערך אפס. הרעיון של מערכת Casper הוא להשתמש בטרנספורמציה של קוד מקור על מנת לעקוב אחר התפשטות זו, מבלי לשנות את ה-JVM. במקרים מסוימים, ניתן ליצור אוטומטית תיקון כדי לתקן חריגות של מצביע האפס.

שפות פונקציונליות טהורות וקוד משתמש המופעל על ידי מפרש או על מכונות וירטואליות אינם סובלים מהבעיה של הפניית מצביע אפס, שכן לא ניתנת גישה ישירה למצביעים.

כאשר שפה אכן מספקת אפשרות לשימוש במצביעים, ייתכן שניתן יהיה להפחית או להימנע מהפניות מצביע אפס בזמן ריצה על ידי בדיקה בזמן הידור, באמצעות ניתוח סטטי או טכניקות אחרות. ניתן לראות גישה זו בגרסאות מודרניות של שפת התכנות אייפל,  D, ו- Rust . 

ניתן לבצע ניתוח דומה באמצעות כלים חיצוניים.

היסטוריה 
בשנת 2009, סר טוני הואר הצהיר שהוא המציא את מצביע האפס בשנת 1965 כחלק משפת ALGOL W. בהתייחסות זו משנת 2009 מתאר הואר את המצאתו כ"טעות של מיליארדי דולרים":

ראו גם
 תו ה-Null

הערות שוליים 

תכנות