הפחדים הגדולים ביותר של מתכנתים כשהם מתעסקים עם מצביעים הם underrun ו overflow. אך יש פיתרון די פשוט לטיפול בסטיה מגודל הזיכרון האפשרי, כמובן לא יפתור את הבעיה עצמה אבל לפחות יבטיח שיהיה מה שיטפל באותו המקרה.
לC++ יש פונקציה בשם _new_handler שמוחזרת באופן אוטומטי על ידי רכיב מסוים ברגע שהוא כושל, כברירת מחדל הפונקציה מכילה NULL. ישנה עוד פונקציה מיוחדת בשם set_new_handler שבאמצעותה המשתמש יכול להגדיר פונקציה מותאמת אישית ל_new_handler.
אני חושב שהקוד ידבר בעד עצמו:
void main( ) { void outofMemory( ); set_new_handler(outofMemory); char *pointer = new char[..Huge value here..]; } void outofMemory( ) { cout<<"System ran out of memory"; exit(1); }d
בדוגמת הקוד הזאת הפונקציה outofMemory ברגע שההשמה במצביע pointer תיכשל עקב חוסר בזיכרון פנוי.
Posted by adar on ינואר 22, 2010 at 10:27 pm
הפונקציה מזהה גם segfault?
Posted by ארתיום on ינואר 23, 2010 at 12:42 pm
הפתרון שלך סביר רק אם אתה רוצה לעצור ולצאת… זה לא תמיד פתרון טוב. בשביל מה ב־C++ יש exceptions?
ב־C++ אופרטור new זורק exception: std::bad_alloc אם הוא נכשל, תשים לב, הוא לא מתנהג כמו malloc ב־C שמחזיר NULL.
אם הקוד שלך exception safe (כמו שהוא אמור להיות) ואתה דואג לתפוס exceptions במקום הנכון אתה פשוט תתפוס std::bad_alloc כמו זזה אמור להיות.
Posted by a on ינואר 24, 2010 at 12:18 am
ארתיום – זה נכון. אבל מה קורה אם שכחת לשים exception על איזשהו new? זה לא *אמור* לקרות, אבל זה עדיין קורה. בצורה כזאת – ניתן לפחות לדעת על זה…
Posted by ארתיום on ינואר 24, 2010 at 7:12 am
למה אתה מתכוון? new זורק exception בעצמו!
אתה לא צריך להגיד לו את זה.
Posted by ManicQin on ינואר 25, 2010 at 9:03 pm
Adar הפונקציה נזרקת רק במצב שnew כשל (מכאן השם 😉 ). היא פשוט מטעינה callback.
נראה לי (לפחות אני מקווה) שA התכוון: מה קורה אם אתה לא מגן על הnew שלך (שם try ו catch).
בכל מקרה מתברר שיש עד היום קומפיילרים שלא זורקים במקרה שnew נכשלה.
אני לא מצאתי לזה הוכחה, אבל יש מצב שstd::bad_alloc נזרק מתוך callback שהמערכת שמה בset_new_handler בברירת מחדל.