False positive error.SwallowedOutOfMemoryError in Word Count

Word Count is broken for me after recent update of tests.

Tests now do std.testing.checkAllAllocationFailures(). This is a good thing in most cases. It helps you to find places where you forgot to errdefer the cleanup. But sometimes it triggers false positives. The documentation says

If an allocation was made to fail during a run of test_fn, but test_fn didn’t return error.OutOfMemory, then error.SwallowedOutOfMemoryError is returned from checkAllAllocationFailures. You may want to ignore this depending on whether or not the code you’re testing includes some strategies for recovering from error.OutOfMemory.

I want to ignore. This is what happened to me.

10/14 test_word_count.test.with quotations...FAIL (SwallowedOutOfMemoryError)
/opt/zig/lib/std/testing.zig:1148:17: 0x115974d in checkAllAllocationFailures__anon_22030 (std.zig)
                return error.SwallowedOutOfMemoryError;
                ^
/mnt/exercism-iteration/test_word_count.zig:171:5: 0x115a9c9 in test.with quotations (test_word_count.zig)
    try std.testing.checkAllAllocationFailures(
    ^

My solution calls std.StringHashMap.getOrPut(). This function recovers from error.OutOfMemory. Comments in source:

    // If allocation fails, try to do the lookup anyway.
    // If we find an existing item, we can return it.
    // Otherwise return the error, we could not add another.

Please disable error.SwallowedOutOfMemoryError and allow me to use the standard library function that fits this exercise nicely.

So more people understand what we are discussing.:

I first learned C++ before it had exceptions. At the time, it was reasonable to write

f(new A(), new B());

Years later, I read Exceptional C++. It pointed out that an exception could be thrown during allocation or construction of the second object, in which case the first object would be leaked. Functions like f should be rewritten to accept unique_ptr instead of raw pointers, and calls should be rewritten to use make_unique instead of new.

I would have welcomed a way to automatically detect such bugs.

The Zig programming language now has a convenient way for unit tests to detect these sorts of leaks, at least in the context of allocation failure. checkAllAllocationFailures calls a test function and record the number of memory allocations, n . It then calls the test function n more times, forcing memory allocation to fail during the 1st allocation , or 2nd allocation, …, or nth allocation.

I recently updated various Zig exercise tests to use checkAllAllocationFailures:

anagram
pascals-triangle
proverb
resistor-color-trio
word-count

I didn’t use [no important files changed], as the majority of student solutions fail, including my own first submissions.

I would like to increase the difficulty of Zig word-count to 8, and perhaps add a hint or instructions append.

1 Like

Does your preferred solution pass with draft PR #493 ?

Yes. Thank you.