פתרון פירוק מחסנית וספריות ריצה¶
האובייקט שמוגדר אחרי הקריאה ל־inner לא נבנה במסלול שמסתיים בזריקה. לכן אין לו destructor להריץ. המהדר צריך להבחין בין מצבי התקדמות שונים בתוך אותה פונקציה, ולא רק לדעת שקיימים בה שלושה משתנים.
אפשר להוסיף את הקטע הבא ל־outer כדי לראות את ההבדל. במסלול רגיל מגיעים גם ל־after; במסלול הכשל הוא אינו קיים.
הקוד מחליף את ההגדרה הקודמת, ובניסוי האסמבלי אפשר להשאיר את noinline. סדר ההשמדה של האובייקטים שנבנו הוא הפוך לסדר השלמת הבנייה שלהם.
השחזור של הקורא דורש את מיקום ההוראה, את תיאור שינוי המחסנית ואת מיקומי הרגיסטרים שנשמרו. ב־x64 אין להניח שרגיסטר RBP מצביע תמיד לשרשרת frames קבועה. המהדר יכול להשתמש בו למטרה אחרת או לא להשתמש בו כלל כ־frame pointer.
ממשק בעלות אפשרי משתמש בחתימות הבאות. זהו header לחוזה, ולא מימוש של ההקצאה.
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
int make_bytes(unsigned char** out, size_t* size);
void release_bytes(unsigned char* value);
#ifdef __cplusplus
}
#endif
היצירה מאפסת פלטים לפני ניסיון העבודה. הצלחה מעבירה ללקוח בעלות שחייבת לחזור דרך release_bytes. כשל אינו מעביר בעלות. הלקוח אינו קורא delete[] או free, והספרייה אינה שומרת העתק נסתר שממשיך להשתמש באחסון אחרי השחרור.
בחלופה שבה הלקוח מספק אחסון, הפונקציה מקבלת pointer ו־capacity ומחזירה אורך נדרש או כתוב. חייבים להגדיר אם buffer קטן גורם לכתיבה חלקית, אם אפשר לקרוא עם null כדי לברר גודל ומה קורה כשהגודל משתנה בין שתי הקריאות.
תפיסת access violation אינה מתקנת את הכתיבה שגרמה לו. ייתכן שמבנה ניהולי כבר נפגם, וייתכן שהתקלה התגלתה רק בפעולת שחרור מאוחרת. עצירה בדיבאגר ושמירת dump מאפשרות לחקור את ההקשר; המשך שקט יכול למחוק ראיות וליצור נזק נוסף בתוך התהליך.
הבדיקה החשובה היא שהתיקון משחזר אינווריאנט, ולא רק משנה את הדרך שבה הודעת הכשל מוצגת.