flak rss random

memory leak proof every C program

Memory leaks have plagued C programs for as long as the language has existed. Many solutions have been proposed, even going so far as to suggest we should rewrite C programs in other languages. But there’s a better way.

Presented here is a simple solution that will eliminate the memory leaks from every C program. Link this into your program, and memory leaks are a thing of the past.

#include <dlfcn.h>
#include <stdio.h>

struct leaksaver {
        struct leaksaver *next;
        void *pointer;
} *bigbucket;

void *
malloc(size_t len)
        static void *(*nextmalloc)(size_t);
        nextmalloc = dlsym(RTLD_NEXT, "malloc");
        void *ptr = nextmalloc(len);
        if (ptr) {
                struct leaksaver *saver = nextmalloc(sizeof(*saver));
                saver->pointer = ptr;
                saver->next = bigbucket;
                bigbucket = saver;
        return ptr;

Every allocated pointer is saved in the big bucket, where it remains accessible. Even if no other references to the pointer exist in the program, the pointer has not leaked.

It is now entirely optional to call free. If you don’t call free, memory usage will increase over time, but technically, it’s not a leak. As an optimization, you may choose to call free to reduce memory, but again, strictly optional.

Problem sovled!

Posted 19 Jan 2024 16:55 by tedu Updated: 19 Jan 2024 16:55
Tagged: c programming rants

on the efficacy of cosmic ray sorting

Cosmic rays are believed by some to exist, although I’ve never seen one. Have you? Are the cosmic rays in the room with us now? It has been further claimed that these cosmic rays may interact with our computers, possibly causing strange behaviors. This sounds like pseudo scientific babble from people who don’t believe in the ghost in the machine.


Posted 28 Apr 2022 18:13 by tedu Updated: 28 Apr 2022 18:13
Tagged: c programming

cgo does clear errno

C functions commonly, though not universally, provide information about a failure through the global variable like errno. Provide, not indicate. If there’s no error, as indicated by the function’s normal return value, the value and meaning of errno is unreliable.


Posted 15 Apr 2022 17:07 by tedu Updated: 15 Apr 2022 17:51
Tagged: c go programming

small views of large files

Sometimes you have a large file when you want a small file. You may not be able to edit the large file, but that’s okay, you can simply read the small part you want out of the large file. libfdview is a proof of concept library that presents a smaller view of a larger file.


Posted 22 Sep 2020 20:00 by tedu Updated: 22 Sep 2020 20:00
Tagged: c programming

Cenum safety warning

Before relying on compiler warnings for enum mismatches, it’s important to know when or if such warnings will be generated.


Posted 30 Jul 2020 20:07 by tedu Updated: 30 Jul 2020 20:07
Tagged: c programming

three valued structs

Sometimes we have a boolean, which is great for storing two values, but we need just a little more space to squeeze in a third value. There’s a few ways to do this.


Posted 29 Jul 2020 06:20 by tedu Updated: 06 Aug 2020 01:17
Tagged: c programming

embedding binary objects in c

You have a blob of some data which you would like to embed into your C program. Perhaps a splash screen, or a special font, firmware for your scsi card, or whatever. The usual approach which I think most people are familiar with is to run something like xxd -i to generate a source file with a large array of hex constants. Or write your own little script for that purpose.


Posted 16 Apr 2020 11:02 by tedu Updated: 16 Apr 2020 11:02
Tagged: c programming

fixing telnet fixes

There’s a FreeBSD commit to telnet. fix a couple of snprintf() buffer overflows. It’s received a bit of attention for various reasons, telnet in 2019?, etc. I thought I’d take a look. Here’s a few random observations.

Here are three new lines, after the patch.

                unsigned int buflen = strlen(hbuf) + strlen(cp2) + 1;
		cp = (char *)malloc(sizeof(char)*buflen);
		snprintf((char *)cp, buflen, "%s%s", hbuf, cp2);

1. The first line is indented with spaces while the others use tabs.

2. The correct type for string length is size_t not unsigned int.

3. sizeof(char) is always one. There’s no need to multiply by it.

4. If you do need to multiply by a size, this is an unsafe pattern. Use calloc or something similar. (OpenBSD provides reallocarray to avoid zeroing cost of calloc.)

5. Return value of malloc doesn’t need to be cast. In fact, should not be, lest you disguise a warning.

6. Return value of malloc is not checked for NULL.

7. No reason to cast cp to char * when passing to snprintf. It already is that type. And if it weren’t, what are you doing?

8. The whole operation could be simplified by using asprintf.

9. Although unlikely (probably impossible here, but more generally), adding the two source lengths together can overflow, resulting in truncation with an unchecked snprintf call. asprintf avoids this failure case.

Posted 11 Jul 2019 04:13 by tedu Updated: 11 Jul 2019 04:13
Tagged: c programming

xterm full reverse

Depending on whether it is day or night, I prefer a light screen or a dark screen. I would like switching between these two modes of operation to be quick and easy. Easy in this case means I am willing to run a command, but not ctrl-click on 21 different xterms.


Posted 13 Dec 2018 21:14 by tedu Updated: 24 Dec 2023 17:17
Tagged: c programming x11

strict structs

Contrary to popular belief, C does have types. It even has type qualifiers. Unfortunately, the selection is somewhat limited and there are several implicit conversions that may lead to less than robust code. The good news is that with a little effort we can define our own types and enforce our own rules. I’ve forgotten where I first saw this, and don’t really have a good name for it.


Posted 14 Nov 2018 15:45 by tedu Updated: 14 Nov 2018 15:45
Tagged: c programming