We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← RAII: Objects With Lifetimes step 3 of 4
Let a vector own the histogram buckets
Manual cleanup can be skipped when control leaves a function early:
Buffer* b = new Buffer(size);
use(b);
delete b;
If use throws and an outer handler catches the exception, the delete expression is never reached. The pointer itself does not own or destroy the Buffer. A return inserted before delete would have the same cleanup problem.
Prefer a local object, container or smart pointer that owns the resource. Its destructor handles cleanup when its scope ends normally or is unwound. Low-level allocation code may still need new and delete, but ordinary callers should usually work with an owning type.
Choose ownership to match the task
| Need | Typical choice |
|---|---|
| An object whose lifetime fits a scope | A local object |
| A runtime-sized sequence | std::vector<T> |
| A dynamically allocated object with one owner | std::unique_ptr<T>, usually created with std::make_unique |
| An object whose lifetime genuinely needs shared ownership | std::shared_ptr<T> |
Returning an object does not by itself require dynamic allocation; returning by value is often suitable. A local object may also allocate internally, as a vector does for its elements. Automatic cleanup is an ownership property, not a promise that construction is free or that no allocation occurs.
When manually managing an ordinary new T[n] array, use the matching delete[] form. Using scalar delete on that array has undefined behavior. Tools may diagnose a mismatch, but a successful compilation does not prove it safe.
Your task
Rewrite:
std::vector<int> histogram(const std::vector<int>& values, int buckets);
Use a local std::vector<Cell> to own the bucket counters. Keep Cell and
live_cells unchanged, and remove the new[] and delete[] expressions from
histogram. The supplied = delete declarations disable copying; leave them
in place. They are unrelated to deallocating an object.
Apply these rules:
- If buckets <= 0, return an empty vector before doing remainder arithmetic.
- Otherwise, begin with buckets counters, each zero.
- Ignore negative values.
- If any value is greater than 1,000,000, discard the entire histogram and return empty. Exactly 1,000,000 is allowed.
- For each remaining value v, increment bucket
v % buckets. - Return the counts in bucket order, from index 0 to buckets - 1.
Inputs and each resulting count fit int; test bucket counts are small enough
for the allocation. Leave values unchanged. Empty input with three buckets
returns [0, 0, 0], not an empty vector.
For values = [-1, 0, 1, 2, 5] and buckets = 3, ignore -1 and count the
remaining remainders 0, 1, 2 and 2. The result is [1, 1, 2].
What the harness checks
Every Cell constructor increments live_cells; its destructor decrements it.
The harness returns [counts, live_cells] after histogram has returned, and
live_cells must be zero. For the example above, expect [[1, 1, 2], 0].
In the starter, buckets <= 0 returns before allocation. The normal path
deletes the array, but finding a value above the limit returns after allocation
without deleting it. For [1, 2000000, 3] and two buckets, the starter returns
an empty histogram but leaves two Cells alive. The required output is [[], 0].
A local vector destroys its Cells on either return path and also during exception unwinding. The live counter makes this specific ownership mistake visible; it does not detect every possible memory leak.
Construct the counter vector with a size argument in parentheses:
std::vector<Cell> counts(static_cast<std::size_t>(buckets));
This constructs that many Cells, whose n member starts at zero. Braces can
prefer an initializer-list constructor when one is viable, as in
std::vector<int>{3}, which contains one value. The result depends on the
element type and available constructors, so braces do not universally mean
an element list. Parentheses express the intended count clearly here.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
C++ reference solution
Sign in to track your attempts toward unlocking the reference solution.