bug-ncurses
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A Valgrind-observant ncurses


From: Bill Gray
Subject: Re: A Valgrind-observant ncurses
Date: Thu, 20 Jun 2024 13:06:54 -0400
User-agent: Mozilla Thunderbird

Hi Branden,  all,

On 6/20/24 11:12, G. Branden Robinson wrote:
Hi Bill,
    ...It's five blocks unless printw() is called;  apparently,
    that function maintains a static buffer that isn't freed.

What do you mean by "static" here?

Sorry, I was sloppy in my language there. You're right; a 'static buffer' should be assumed to be one declared as, say,

static char buffer[80];

What I meant was that you have a buffer that is allocated when printw() is first called, and possibly resized if it needs to be made larger. On the first call to printw(), it might allocate an 80 byte buffer, figuring that'll be big enough 99% of the time. Then, when it encounters a printw() that requires 200 bytes, the buffer is re-allocated to be (say) 300 bytes. Subsequent calls may exceed even that limit, and cause the buffer to be re-re-allocated to be still larger.

Ideally, the buffer is then freed when endwin() or delscreen() is called. Except that doesn't happen here.

Again, that isn't a 'bug'; it just means that the buffer will remain allocated until the program ends, and Valgrind will tell you that you have a buffer that _could_ be freed (the program still has a pointer to it), but which wasn't. Frequent Valgrind users (hand raised here) will be at least mildly annoyed by this.

You are correct, of course, that Valgrind won't complain about a memory leak from a "real" static buffer.

-- Bill

  My training and experience in C is
that a "static buffer" is one that is "statically" allocated, that is at
compile time, and in object files traditionally appears in a ".data" or
".bss" segment--the latter if initialized zero/empty (cf. ".text", and
".rodata" segments).

Memory can't leak from static allocations because they are of fixed
size.  Only dynamic, a.k.a. run-time allocations, can do so.  So if
printw() is using a static buffer, I'm wondering why Valgrind complains
about it at all.

But from what I see in the aforementioned log file, printw() (an
ncurses function) doesn't only use static buffers; it calls an internal
function _nc_printf_string_sp() which in turn calls malloc()--in other
words, a dynamic memory allocation.

Quite possible there's something about valgrind's diagnostics I don't
understand here.

Meanwhile, is the OP familiar with the `--disable-leaks` flag ncurses
offers in its "configure" script?

INSTALL:
     --disable-leaks
         For testing, compile-in code that frees memory that normally would not
         be freed, to simplify analysis of memory-leaks.

         Any implementation of curses must not free the memory associated with
         a screen, since (even after calling endwin()), it must be available
         for use in the next call to refresh().  There are also chunks of
         memory held for performance reasons.  That makes it hard to analyze
         curses applications for memory leaks.  To work around this, build a
         debugging version of the ncurses library which frees those chunks
         which it can, and provides the _nc_free_and_exit() function to free
         the remainder and then exit.  The ncurses utility and test programs
         use this feature, e.g., via the ExitProgram() macro.

         Because this lies outside of the library's intended usage, it is not
         normally considered part of the ABI.  If there were some (as yet
         unplanned) extension which frees memory in a manner that would let the
         library resume and reallocate memory, then that would not use a "_nc_"
         prefix.

Regards,
Branden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]