[{"data":1,"prerenderedAt":425},["ShallowReactive",2],{"home-lessons":3},[4,166,291],{"id":5,"title":6,"body":7,"description":131,"extension":132,"label":133,"lessonId":134,"meta":135,"minutes":136,"navigation":137,"order":138,"path":139,"quiz":140,"seo":163,"slug":134,"stem":164,"__hash__":165},"lessons\u002Flessons\u002Fownership.md","Someone has to clean up.",{"type":8,"value":9,"toc":126},"minimark",[10,15,19,26,68,75,79,90,97,101,107,112,122],[11,12,14],"h2",{"id":13},"the-mess","The mess",[16,17,18],"p",{},"Your AI leaves a “remember to free this” comment. Adorable. Comments are famously terrible garbage collectors.",[16,20,21,25],{},[22,23,24],"strong",{},"Ownership means responsibility for cleanup."," Think of a borrowed apartment key: knowing the address doesn't make you the landlord. A raw pointer stores an address; it doesn't tell you who must release the resource.",[27,28,33],"pre",{"className":29,"code":30,"language":31,"meta":32,"style":32},"language-cpp shiki shiki-themes github-light github-dark","void process() {\n    auto* buffer = new int[64];\n    if (!ready()) return; \u002F\u002F The comment will clean up. Surely.\n    delete[] buffer;\n}\n","cpp","",[34,35,36,44,50,56,62],"code",{"__ignoreMap":32},[37,38,41],"span",{"class":39,"line":40},"line",1,[37,42,43],{},"void process() {\n",[37,45,47],{"class":39,"line":46},2,[37,48,49],{},"    auto* buffer = new int[64];\n",[37,51,53],{"class":39,"line":52},3,[37,54,55],{},"    if (!ready()) return; \u002F\u002F The comment will clean up. Surely.\n",[37,57,59],{"class":39,"line":58},4,[37,60,61],{},"    delete[] buffer;\n",[37,63,65],{"class":39,"line":64},5,[37,66,67],{},"}\n",[16,69,70,71,74],{},"If ",[34,72,73],{},"ready()"," returns false, the pointer disappears and the allocation stays. You've invented a donation scheme for RAM.",[11,76,78],{"id":77},"the-fix","The fix",[16,80,81,82,85,86,89],{},"Use ",[34,83,84],{},"std::vector\u003Cint>"," for this buffer: it owns its storage and releases it on destruction. For a single separately owned object, consider ",[34,87,88],{},"std::unique_ptr",".",[16,91,92,93,96],{},"Several functions can borrow an object without owning it. Use ",[34,94,95],{},"std::shared_ptr"," only for actual shared ownership; strong reference cycles can prevent cleanup. “Shared everywhere” is a custody dispute, not a design.",[11,98,100],{"id":99},"ask-your-ai","Ask your AI",[102,103,104],"blockquote",{},[16,105,106],{},"Name each resource's owner. Show cleanup on success, early return, and exceptions. Use an owning type; justify any shared ownership.",[16,108,109],{},[22,110,111],{},"No named owner? No convincing cleanup story. Reject the hand-waving.",[16,113,114,115,89],{},"Receipts: ",[116,117,121],"a",{"href":118,"rel":119},"https:\u002F\u002Fisocpp.github.io\u002FCppCoreGuidelines\u002FCppCoreGuidelines#S-resource",[120],"nofollow","C++ Core Guidelines — resource management",[123,124,125],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":32,"searchDepth":46,"depth":46,"links":127},[128,129,130],{"id":13,"depth":46,"text":14},{"id":77,"depth":46,"text":78},{"id":99,"depth":46,"text":100},"Your AI allocated it. Your comment won’t free it. Someone needs an actual job.","md","OWNERSHIP","ownership",{},"2",true,"1","\u002Flessons\u002Fownership",[141,148,156],{"prompt":142,"options":143,"answer":40,"explanation":147},"Two raw pointers, same address. How many owners does that prove?",[144,145,146],"Two: each pointer owns the target.","You cannot infer ownership from addresses.","One: whichever pointer was created first.","An address shows where, not who cleans up. Owning types express responsibility. Pointer counting is not an ownership model.",{"prompt":149,"options":150,"answer":154,"explanation":155},"An early return skips manual cleanup. What needs fixing?",[151,152,153],"Give the resource an owner that handles every ordinary exit.","Add cleanup after the return.","Give the raw pointer a shorter scope.",0,"An owning object cleans up on destruction. An unreachable delete is just decorative punctuation.",{"prompt":157,"options":158,"answer":46,"explanation":162},"The AI uses shared_ptr everywhere. Problem solved?",[159,160,161],"Yes: shared pointers cannot leak.","Yes: every borrower needs shared ownership.","No: shared ownership needs a reason; strong cycles can leak.","Borrowing needs no ownership share. Strong cycles can prevent cleanup. You made a reference-counted group project.",{"title":6,"description":131},"lessons\u002Fownership","0j5YP6N0LZBF_HC7Qj5WlSH_CVojrQcAltFCbxygVlo",{"id":167,"title":168,"body":169,"description":261,"extension":132,"label":262,"lessonId":263,"meta":264,"minutes":136,"navigation":137,"order":136,"path":265,"quiz":266,"seo":288,"slug":263,"stem":289,"__hash__":290},"lessons\u002Flessons\u002Flifetime.md","Your pointer outlived its welcome.",{"type":8,"value":170,"toc":256},[171,173,176,182,206,216,218,225,228,234,236,241,254],[11,172,14],{"id":13},[16,174,175],{},"The AI returns a pointer to a local variable. You check that it isn't null. Excellent. You've confirmed the corpse has an address.",[16,177,178,181],{},[22,179,180],{},"Lifetime is how long an object exists."," Your hotel room number survives checkout. Your booking doesn't. A pointer is the room number, not a lifetime extension.",[27,183,185],{"className":29,"code":184,"language":31,"meta":32,"style":32},"int* getAnswer() {\n    int answer = 42;\n    return &answer; \u002F\u002F Forwarding address for a dead local.\n}\n",[34,186,187,192,197,202],{"__ignoreMap":32},[37,188,189],{"class":39,"line":40},[37,190,191],{},"int* getAnswer() {\n",[37,193,194],{"class":39,"line":46},[37,195,196],{},"    int answer = 42;\n",[37,198,199],{"class":39,"line":52},[37,200,201],{},"    return &answer; \u002F\u002F Forwarding address for a dead local.\n",[37,203,204],{"class":39,"line":58},[37,205,67],{},[16,207,208,211,212,215],{},[34,209,210],{},"answer"," dies when the function returns. Reading through that pointer afterward is ",[22,213,214],{},"undefined behavior",": C++ promises no particular result. A successful demo doesn't resurrect anything.",[11,217,78],{"id":77},[16,219,220,221,224],{},"Return this integer ",[22,222,223],{},"by value",". The caller gets a value instead of depending on a dead local.",[16,226,227],{},"The same trap catches callbacks that borrow locals and run later. Give the callback data it owns, where appropriate, or otherwise keep its target alive through every use.",[16,229,230,233],{},[22,231,232],{},"Non-null doesn't mean alive."," Stop asking a null check to perform a séance.",[11,235,100],{"id":99},[102,237,238],{},[16,239,240],{},"When does this target die? Can any returned pointer or delayed callback outlive it? Fix the lifetime and explain why every use stays valid.",[16,242,114,243,248,249,89],{},[116,244,247],{"href":245,"rel":246},"https:\u002F\u002Feel.is\u002Fc++draft\u002Fbasic.life",[120],"Object lifetime"," · ",[116,250,253],{"href":251,"rel":252},"https:\u002F\u002Feel.is\u002Fc++draft\u002Fstmt.return",[120],"Return statements",[123,255,125],{},{"title":32,"searchDepth":46,"depth":46,"links":257},[258,259,260],{"id":13,"depth":46,"text":14},{"id":77,"depth":46,"text":78},{"id":99,"depth":46,"text":100},"The object died. Your pointer kept the address. Very thoughtful. Completely useless.","LIFETIME","lifetime",{},"\u002Flessons\u002Flifetime",[267,274,281],{"prompt":268,"options":269,"answer":46,"explanation":273},"Read through a returned pointer to a dead local. What happens?",[270,271,272],"The pointer keeps the local alive.","The old value is guaranteed until the next call.","Undefined behavior: the target no longer exists.","Returning an address does not extend this lifetime. The variable died. Your confidence attended neither the funeral nor the review.",{"prompt":275,"options":276,"answer":40,"explanation":280},"A pointer passes a null check. What have you proved?",[277,278,279],"Its target is alive.","Only that the pointer is not null.","It is safe to dereference once.","Dangling pointers can be non-null. Congratulations: you checked the address, not whether anyone lives there.",{"prompt":282,"options":283,"answer":154,"explanation":287},"A callback borrows a local and runs after it dies. The fix?",[284,285,286],"Own suitable data or otherwise keep the target alive.","Make the borrowed reference const.","Check the pointer before scheduling the callback.","The target must survive every access. Owning a suitable copy can help. Running later does not make death negotiable.",{"title":168,"description":261},"lessons\u002Flifetime","62ycXtxO89d0F1gj62Efq7PAwUgNV70p2wQnlENuM0g",{"id":292,"title":293,"body":294,"description":394,"extension":132,"label":395,"lessonId":396,"meta":397,"minutes":136,"navigation":137,"order":398,"path":399,"quiz":400,"seo":422,"slug":396,"stem":423,"__hash__":424},"lessons\u002Flessons\u002Freferences-and-pointers.md","Borrowed doesn’t mean immortal.",{"type":8,"value":295,"toc":389},[296,298,301,316,341,344,346,353,363,368,370,375,387],[11,297,14],{"id":13},[16,299,300],{},"Your AI replaces copies with borrowed access. “Optimized.” Yes, accessing dead storage is wonderfully cheap if correctness isn't a requirement.",[16,302,303,304,307,308,311,312,315],{},"A ",[22,305,306],{},"reference"," aliases an object; a ",[22,309,310],{},"pointer"," stores an address. A ",[22,313,314],{},"view"," borrows data. None automatically keeps its target alive. Having someone's address doesn't stop them moving.",[27,317,319],{"className":29,"code":318,"language":31,"meta":32,"style":32},"std::vector\u003Cint> scores{10};\nint* first = &scores[0];\nscores.reserve(scores.capacity() + 1); \u002F\u002F New storage, if successful.\nstd::cout \u003C\u003C *first;                  \u002F\u002F Visiting the demolished house.\n",[34,320,321,326,331,336],{"__ignoreMap":32},[37,322,323],{"class":39,"line":40},[37,324,325],{},"std::vector\u003Cint> scores{10};\n",[37,327,328],{"class":39,"line":46},[37,329,330],{},"int* first = &scores[0];\n",[37,332,333],{"class":39,"line":52},[37,334,335],{},"scores.reserve(scores.capacity() + 1); \u002F\u002F New storage, if successful.\n",[37,337,338],{"class":39,"line":58},[37,339,340],{},"std::cout \u003C\u003C *first;                  \u002F\u002F Visiting the demolished house.\n",[16,342,343],{},"Assume the requested capacity is representable. Successful reallocation invalidates pointers and references to the old elements. The vector survives. Your pointer's usefulness doesn't.",[11,345,78],{"id":77},[16,347,348,349,352],{},"Obtain the element again ",[22,350,351],{},"after"," reallocation, checking that the index is valid. Or prevent invalidation while borrowing.",[16,354,303,355,358,359,362],{},[34,356,357],{},"std::string_view"," also needs its backing characters to remain alive and valid. ",[34,360,361],{},"const"," restricts modification through an access path; it isn't life insurance.",[16,364,365],{},[22,366,367],{},"Check both lifetime and invalidation. “The container still exists” is half a defense.",[11,369,100],{"id":99},[102,371,372],{},[16,373,374],{},"Who owns this borrowed data? What destroys or invalidates it? Fix every use that crosses either event, citing the container's guarantees.",[16,376,114,377,248,382,89],{},[116,378,381],{"href":379,"rel":380},"https:\u002F\u002Feel.is\u002Fc++draft\u002Fvector.capacity",[120],"Vector reallocation",[116,383,386],{"href":384,"rel":385},"https:\u002F\u002Feel.is\u002Fc++draft\u002Fstring.view.template",[120],"String views",[123,388,125],{},{"title":32,"searchDepth":46,"depth":46,"links":390},[391,392,393],{"id":13,"depth":46,"text":14},{"id":77,"depth":46,"text":78},{"id":99,"depth":46,"text":100},"“Zero-copy.” Also zero guarantees that the thing you borrowed still exists. Nice optimization.","REFERENCES & POINTERS","references-and-pointers",{},"3","\u002Flessons\u002Freferences-and-pointers",[401,408,415],{"prompt":402,"options":403,"answer":154,"explanation":407},"Does string_view keep its backing string alive?",[404,405,406],"No: the characters must stay alive and valid separately.","Yes: it shares ownership.","Only if the view is const.","A view borrows characters. It owns precisely none of them. Budget accordingly.",{"prompt":409,"options":410,"answer":40,"explanation":414},"A vector reallocates. Can you use an old element pointer?",[411,412,413],"Yes: the vector itself still exists.","No: reallocation invalidated it.","Yes: the element value is unchanged.","The vector replaced its storage. Same container, dead address. Your pointer missed the moving announcement.",{"prompt":416,"options":417,"answer":46,"explanation":421},"What lifetime guarantee does const access provide by itself?",[418,419,420],"The target lives as long as the reference.","The owner cannot destroy the target.","None: restricted mutation is not lifetime management.","Const restricts modification through that access. It is not cryogenic storage. Specific temporary-lifetime rules are a separate topic.",{"title":293,"description":394},"lessons\u002Freferences-and-pointers","KBhQ4Tb6NSSvwpoEXGEDnAHBEcxhg7X2ZnVdkSqgz9k",1789406997068]