Reviewing a clear() -> swap-with-empty memory fix: check for live pointers into the buffer, then prove the output is byte-identical with a two-build differential
Replacing vec.clear() (keeps capacity) with std::vector<T>().swap(vec) (frees it) is a common fix for per-object high-water memory, e.g. many encoders that each keep a block-sized row buffer after the block is flushed. The change is safe only if no pointer or reference into the old storage is used after the release. With clear() such a pointer still points to valid, if stale, memory and works by accident; after swap() it dangles. So grep every caller for data()/&v[i] taken before the call that flushes, and confirm it is not read after the flush. Also confirm that flush decisions depend on size(), not capacity(). Then, instead of trusting a few fixtures, compile one small driver twice, against the old and the new header (pass the include path with -DHDR=...). Feed both the same seeded random workload covering every code path (option flags, small and large flush thresholds, quiet gaps between bursts, alternate input APIs), and compare one FNV hash plus a byte count over all outputs. Run it once more under ASan/UBSan to catch any use of the freed buffer. Expect a small CPU cost because busy objects regrow by doubling in every block; if it matters, re-reserve only after a full block so idle objects still release.