C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Deliberate memory leak

From: Robin Savonen Söderholm <robinsavonensoderholm_at_[hidden]>
Date: Fri, 11 Oct 2024 13:14:14 +0200
Why not deallocate it in main in the end in that case? I honestly think
that you should always free your resources..

// Robin

On Fri, Oct 11, 2024, 13:12 Frederick Virchanza Gotham via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> There are times when we allocate memory which we never intend to
> deallocate. For example, I'm writing a program at the moment that
> loads in plugins, and the plugins stay loaded until the end of the
> program.
>
> The only problem with this is that when you run a debugging tool to
> detect memory leaks, you get a load of false positives. I had a
> program before that linked with libpango, and I spent ages trying to
> find a memory leak, wondering if I was misusing the library or if the
> library internally had a bug, and I went the whole hog and joined the
> libpango mailing list and shared all my debugging output. In the end
> it turned out to be a benign memory leak -- i.e. the allocation
> happened once in the program and was intended to last the entire
> program.
>
> But what if we could do the following:
>
> void *p = malloc( 1024ul * 1024ul * 64ul );
> std::deliberate_leak(p);
>
> Or:
>
> long unsigned *p = new long unsigned[2048u];
> std::deliberate_leak(p);
>
> It could work something like this: https://godbolt.org/z/Gx6Pc6ne5
>
> And then when you compile in Release Mode, you don't bother deallocating.
>
> And here it is copy-pasted:
>
> #include <cstdlib> // abort, atexit, free
> #include <mutex> // lock_guard, mutex
>
> #define PRINT_TO_SCREEN // ------- You can comment this line out -------
>
> #ifdef PRINT_TO_SCREEN
> # include <cstdint> // uintptr_t
> # include <iomanip> // hex
> # include <iostream> // cout, endl
> #endif
>
> void DeliberateLeak(void const volatile *const arg) noexcept
> {
> constexpr unsigned capacity = 64u;
> static void const volatile *leaks[capacity] = {}; // all nullptr's
>
> static std::mutex m;
> std::lock_guard mylock(m);
>
> if ( nullptr == leaks[0u] )
> {
> std::atexit(
> [](void) noexcept -> void
> {
> for ( unsigned i = 0u; i < capacity; ++i )
> {
> if ( nullptr == leaks[i] ) return;
> std::free( const_cast<void*>(leaks[i]) );
> #ifdef PRINT_TO_SCREEN
> std::cout << "Freeing deliberately leaked memory
> at address 0x"
> << std::hex
> << reinterpret_cast<std::uintptr_t>(leaks[i])
> << std::endl;
> #endif
> }
> });
> }
>
> static unsigned index = 0u;
> if ( index >= capacity ) std::abort(); // no more free slots available
> leaks[index++] = arg;
> }
>
> int main(void)
> {
> void *p1 = std::malloc(1024ul * 1024ul * 64ul);
> DeliberateLeak(p1);
> void *p2 = std::malloc(1024ul * 1024ul * 64ul);
> DeliberateLeak(p2);
> }
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2024-10-11 11:14:29