Relatively easy ways to catch memory errors

If you're using XS and C in your Perl module, you might have to worry about memory errors. There are tools like valgrind or memory sanitizer which you can use of course:

valgrind perl -I blib/lib -I blib/arch ./mytestscript

or if your problems are even more serious ones like segmentation fault errors you can run Perl under a debugger like gdb:

gdb perl
% run -I blib/lib -I blib/arch ./mytestscript

However, it might be worth noting some "easy" ways to catch memory errors which actually catch a lot of things.

The first thing is setting the variable to 0 after freeing:

 free (result);
 result = 0;

This prevents you from using the variable again accidentally after freeing, although free (0) is actually not an error, so it doesn't prevent you freeing it twice.

Another way which catches quite a lot of careless mistakes is counting mallocs and frees:

 x = malloc (100);
 n_mallocs++;
 y = malloc (300);
 n_mallocs++;

 free (x);
 n_mallocs--;

then at the end of the program:

 if (n_mallocs != 0) {
      fprintf (stderr, "n_mallocs = %d\n", n_mallocs);
 }

I was talking to a friend who works as a surgical assistant about something I saw on "Tomorrow's World" where they had a very complicated machine for ensuring that surgical equipment doesn't get left in people's bodies. It used all kinds of pattern recognition to identify instruments as they were checked out of the sterilizer and then returned. I was quite surprised when she told me that the way that they do that is to always count how many instruments they have issued and then count how many they have returned to the sterilizer. Similar to just counting the mallocs, it's a much simpler but equally effective method for detecting unfreed memory.

For example, in this module I made the n_mallocs counter part of the structure which contains the JSON information. In this module I put the counter and the memory assignment inside a macro, which is probably a good way to make sure not to forget to increment. But if you do forget to increment or decrement, the error message will trip during testing, and you'll quickly find out.

There are lots of other things you can do, such as using memory sanitizer etc., but these easy methods actually get a lot of the problems.

Leave a comment

About Ben Bullock

user-pic Perl user since about 2006, I have also released some CPAN modules.