Memory Lifecycle Drills, Explained with Code Examples

UPI Study › Courses › C++ Programming › Free lessons › Lesson 10.9 Free with a free account

Memory Lifecycle Drills

C++ Programming · Chapter 10: File Access and MemorySection 10.9 · lesson 77 of 84video coming soon

← Detecting and Eliminating Memory LeaksNext lesson: How Child Classes Inherit From Parents →

Earn 3 college credits for C++ ProgrammingRecommended for credit by NCCRS · Computer Science 242 · self-paced · one payment, lifetime access

In this lesson

Allocate, use, and release safely.

  • State the ownership rule every allocation must satisfy
  • Recognize the 4 faults from a checking tool's report
  • Diagnose and repair a leaking program
  • Write owning types, and ownership statements

Transcript

Everything said in the video, section by section (1,870 words). Read along, or search it.

Opening Hook

A Bug No Test Would Show

Picture a program that builds, runs, and prints exactly the right answer. And it has a bug that no test would ever show you. No new syntax appears in this section. What appears is practice. Dynamic memory is the one area where knowing the rules, and reliably applying them, are genuinely different skills. Every drill is paired. Something is allocated, used, and released, and a tool checks whether you actually released it. The reports you'll see are that tool's output, as it prints on Linux.

Core Rule

One Owner, One Release, Every Path

Dynamic allocation hands your program a block of memory, and then steps back. Nothing will reclaim it, nothing will remind you, and nothing will complain if you never do. The whole discipline reduces to one sentence. Every allocation has exactly one owner, and that owner releases it exactly once, on every path out. Each phrase rules out a specific fault. Exactly one owner rules out two pieces of code both believing they must release the same block. Exactly once rules out releasing it twice. And on every path out rules out the most common case of all: a release at the bottom of a function, which some earlier return skips.

Lifecycle

Four Faults in Four Stages

Here's the lifecycle: allocate, use, release, and done. Each of the four faults happens at a particular point. Using the block after release is a use after free. Releasing in the wrong form is a mismatch. If the release is never reached, that's a leak. And if it's reached twice, that's a double release. Only one of those four is a leak. The other three are worse, because they can corrupt data.

Drill One

Checked Array Average with Delete

Drill one. Allocate an array of five whole numbers, fill it with ten through fifty, print their average, and release the array. Then build it with checking switched on. The compiler can't tell you whether memory was released. The program is entirely legal either way. A separate checking tool can, and it's built in. Adding one option, f sanitize equals address, makes every allocation tracked. Here's the correct version. Allocate the array, fill it, and print the average. Then release it with delete, square brackets. And on the next line, set the pointer to null p t r. Run it, and the average is thirty. The tool reports nothing. Setting the pointer to null p t r isn't required, and it's worth the line. A use after release then fails immediately and obviously, instead of quietly reading freed memory. And a second release becomes harmless.

Matching Forms

Brackets Are Part of the Operator

The two forms must be matched exactly. A single value, allocated with new int, is released with plain delete. An array, allocated with new int and a count in brackets, is released with delete and brackets. The brackets are part of the operator, not decoration. Mixing the two is a fault in its own right, even though the memory came from the same place.

Leak Report

Reading the Twenty Byte Leak

Each fault has a distinct signature, so you can diagnose from the message rather than by inspection. Here's a leak, as the tool reports it on Linux. The tool says it detected memory leaks: twenty bytes in one object. Read the second frame. It names the file, and the exact line of the allocation that was never released. That's not the place you should have released it, which the tool can't know. It's the place the block came from. And twenty bytes is five integers, at four bytes each.

Mismatch Report

Array Allocated, Single Value Released

Here's the wrong form of release. The message reads alloc dealloc mismatch, and names both halves: new with brackets, versus plain delete. Allocated as an array, released as a single value. Once seen, it's one of the easier faults to fix. Without the tool, it's undefined behavior, so I won't run it unchecked.

Use After Free

Why Freed Memory Seems to Work

Next, a heap use after free. A block was released, and then read. Without the tool, this often appears to work, because the memory usually still holds the old values for a while. That's precisely what makes it dangerous. It behaves correctly in testing, and fails in use, once something else is allocated over it. The behavior is undefined.

Fault Summary

Four Faults Side by Side

Here are the four faults side by side. A leak means you never released it. Without the tool, nothing is visible. The program grows, and a long-running one eventually fails. Release on every path, or give it an owner. A mismatched release is undefined behavior, and frequently appears to work. The fix is to match the form, always. A use after release usually appears to work, then fails once the memory is reused. Set the pointer to null p t r right after releasing. And a double release is undefined, often a crash, sometimes much later. Keep one owner per allocation, and null p t r makes a second release harmless.

Drill Two

Where Should the Release Go?

Drill two. This program builds, runs, and prints the right answer. Average takes a pointer and a count, and returns the mean. Main allocates five ints, fills them, and prints the average. Build it with checking switched on, and the report will name line thirteen. But should the release go inside average, or in main? Pause here, and decide before going on.

Repair

Fixing the Leak at Line Thirteen

Here's the report. The average is thirty, and then the tool finds a direct leak of twenty bytes, allocated at line thirteen. Line thirteen is the new int allocation. The repair goes in main, which allocated the array: two lines before the return, delete it, then set the pointer to null p t r. Notice what the program didn't do. It didn't crash, misbehave, or print anything wrong. A twenty-byte leak in a program that runs for a tenth of a second is invisible. So the habit has to be formed on small programs, where it doesn't matter yet.

Borrowing

Why Average Must Not Release

And why is this hard to find by reading? Should average release the array? No. It didn't allocate it, and doesn't know whether the caller still needs it. A pointer parameter looks identical whether the function is borrowing the memory, or taking responsibility for it.

Drill Three

An Owning Buffer Class

Every fault so far comes from one source: a release a human has to remember, in the right place, on every path. Constructors and destructors supply the way out. Drill three is an owning buffer. Its constructor allocates the array, fills it with zeros, and prints a message. Its destructor releases the array, and prints a message too, so the pairing is visible. The pointer itself is private, so no using code can release it by hand.

Buffer Output

Release on Scope Exit and Early Exit

Here's the output. Inside use buffer, four ints are allocated, used, and released when the function ends. Then a block is left early, because something goes wrong. Two ints were allocated, and they're released anyway. The tool reports nothing. Nothing in the using code releases anything. The release happens because the object went out of scope, and it happens on the early exit too, without anyone writing a release there.

Drill Four

Building a Grid of Rows

Drill four builds and tears down a grid of three rows by four columns. Each position holds the product of its row and column numbers. A grid built this way isn't one block. It's an array of pointers, each pointing at its own row. So there are four allocations for three rows, and every one needs releasing. Build the pointers first, then each row. Release each row first, then the pointers. Releasing the pointers first would discard the only record of where the rows are. They could never be released at all.

Matrix Output

Forty-Eight Bytes in Three Objects

Allocate matrix creates the array of pointers, then one array per row. Release matrix runs that backward. Every row first, then the array of pointers. Run it, and the grid prints with no report. The drill then asks you to delete the row-releasing loop, and the report is precise about the cost. Forty-eight bytes, in three objects. One object per row, each of four integers, at four bytes each. Reading three objects as one per row is how you locate a partially released structure immediately.

Ownership Statements

Recording Who Is Responsible

The underlying difficulty is that a pointer says nothing about who is responsible for the memory behind it. Since the language won't record it, you must. An ownership statement is one comment, at the point of allocation, and at every function taking the pointer. A function that allocates and returns says the caller owns the result, and must release it. A function that reads says it borrows, and doesn't release. One that takes over says the caller must not use or delete it afterward. And an object holding an allocation says it's released in the destructor.

Design Check

If You Can't Write the Sentence

The statement is also a design check. If you can't write the sentence, the design isn't settled. Whoever finishes with it first describes a fault that hasn't happened yet.

Graded Exercise

Building a Dynamic Reading Log

The graded exercise is a dynamic reading log, for temperature readings. Write a type that owns an array of fractional values. The constructor allocates, the destructor releases, and the size is a const member. Add a borrowing function that returns the highest reading, and a function that returns a new array of readings above a threshold, with its ownership stated. Build a grid of several days by several hours, and release it in the correct order. And include one function that leaves early on invalid input, showing nothing leaks on that path. Submit the sources, a clean checked transcript, a transcript with a deliberate leak, and a one-page note listing every allocation and its owner.

Assessment

How the Marks Are Split

Here's how it's assessed. A quarter of the marks is for pairing. Every allocation released exactly once, on every path, with a clean report. Twenty percent is for the owning type, and fifteen each for the matrix, the ownership statements, and the early exit. The last ten percent is for the deliberate leak, with the line the tool named explained.

Common Mistakes

Three Places Marks Are Lost

Marks are most often lost in three places. A release written only on the normal path. A matrix released outer-first. And ownership statements that don't name an owner.

Key Terms

Ownership and Checking Vocabulary

Ownership is responsibility for releasing an allocation, and it belongs to exactly one piece of code. An ownership statement is a written note, at an allocation or a pointer parameter, saying who releases it. An owning type has a constructor that allocates and a destructor that releases, so the pairing can't be skipped. A path out is any route by which control leaves a function. And a checking tool is a build option that tracks allocations, and reports faults with the file and line of the allocation.

Quick Check

Ownership Statement for Store

Quick check. A function, store, keeps the pointer it's given in a list, and that list deletes it at shutdown. Which ownership statement fits store's parameter? Pause and think. It takes ownership. The list releases the block, so the caller must not use or delete it afterward. Writing borrows there would invite a double release; writing nothing would leave the next reader guessing.

Key Takeaways

Prefer Objects That Cannot Forget

To summarize, in one sentence. Every allocation has one owner, who releases it once, on every path. Match the forms, and set the pointer to null p t r after releasing. Read the report, which names where the block came from. Prefer an object that can't forget, over a person who can. Write the owner down where the memory is allocated, and let a checking tool confirm you were right, rather than assuming it.

About C++ Programming at UPI Study

C++ Programming (Computer Science 242) is a self-paced online course of 84 video lessons in 11 chapters, from your first program to decisions, loops, arrays, functions, classes, files, pointers and inheritance. It carries a NCCRS credit recommendation for 3 semester credits.

Every lesson transcript is free on pages like this one, and the videos are free with a free UPI Study account. Enrolling adds a practice quiz after each lesson, the graded work and final exam that earn the credit, lifetime access, and an official transcript on completion. UPI Study has helped over 130,000 students with college credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Why take it here

Why students take C++ Programming with UPI Study

Your first real programming languageC++ teaches how programs really work: variables, control flow, functions, memory and objects. It is the base for data structures, algorithms, systems and game programming, and for most computer-science degrees.
Credit at a fraction of the priceThe same 3 credits can cost $750 or more at a US college. Here it is one payment, self-paced, with lifetime access.
Finish your degree soonerTransfer credits reduce the courses you still owe, so you can graduate earlier or lighten a heavy semester.
Strengthen an applicationA completed college-level course on an official transcript shows admissions and scholarship committees you can do the work.
Study on your own scheduleNo start dates, no deadlines. Watch the lessons, practice, and take the final when you are ready.
130,000+students helped with college creditsACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Where the credit goes

Universities that work with NCCRS

C++ Programming carries a NCCRS credit recommendation. These universities work with NCCRS; some are UPI Study's signed partners. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.

Find my college → Not listed? Ask Athena in the corner of this page, or book a 15-minute call.

FAQ

Questions students ask us

About Memory Lifecycle Drills

What is the ownership rule every dynamic allocation must satisfy in C++?
Every allocation has exactly one owner, and that owner releases it exactly once, on every path out of the function. Each phrase rules out a fault. One owner prevents two pieces of code from both releasing the same block. Once prevents a double release. Every path prevents a release at the bottom of a function from being skipped by an earlier return.
What are the four memory faults a checking tool like AddressSanitizer reports?
The four faults are a leak, a mismatched release, a use after free, and a double release. A leak means the release was never reached. A mismatch means the wrong form was used, such as plain delete on memory from new int[5]. Use after free reads released memory. Double release frees a block twice. Only the leak is not a corruption risk. Build with -fsanitize=address to track them.
How do I fix a memory leak when the tool points to a line number?
Release the block in the code that allocated it, because the reported line is where the block came from, not where to release it. For example, if main allocates with new int[5] at line thirteen, add delete[] p and then p = nullptr before main returns. A function that only borrows the pointer, like an average function, should not delete it.
How do I write a class that frees its own memory so I can't forget to delete?
Make the class own the allocation: the constructor allocates the array, and the destructor releases it with delete[]. Keep the pointer private so outside code can't release it by hand. The destructor runs when the object goes out of scope, including on an early exit, so no release needs to be written on each path.

About the C++ Programming course

How many college credits is C++ Programming?
C++ Programming (Computer Science 242) carries a NCCRS credit recommendation for 3 semester credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
How much does C++ Programming cost and what is included?
$250, paid once, with lifetime access: all 84 video lessons, a practice quiz after each, the graded work and final exam, and an official transcript when you finish. Students who want several courses choose UPI Study PRO instead.
Which universities accept UPI Study credits?
UPI Study has signed partner agreements with universities such as Thomas Edison State University, University of the People and Charter Oak State College, and works with universities such as Penn State, SNHU and SUNY. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities. Use "Find my college" on this page to check yours.
How long does C++ Programming take?
It is self-paced with no deadlines. The 84 lessons total about 0 hours of video; most students add reading and practice time and finish in a few weeks to a few months, on their own schedule.
How are the exams done?
Quizzes and assignments are online in the course. The final exam is taken online with proctoring; a person on the UPI Study team checks assignments, usually within two days.
How do my credits reach my college?
When the course shows 100% complete, request the official transcript from your dashboard. It is sent to the college you name, and you can send it to more than one. Check your college first with "Find my college" on this page, or ask Athena.

Ready for the full course? Earn 3 credits in C++ Programming.

84 video lessons, a quiz after each one, and the graded work that earns the credit. Recommended for credit by NCCRS.

C++ Programming
3 credits · NCCRS
Enroll →