Search code examples
glibvalamemory-corruption

Vala string processing corrupts memory. Why and how to avoid?


I'm not sure whether I'm misusing Vala or GLib.Regex, because I'm new to both. I've created a minimal example, which reproduces the error. From the following code, I'd expect that it prints a INPUTX b six times, prefixed with source and result alternatingly:

public class Test
{
    public static void run( string src )
    {
        var regex = new Regex( "INPUT[0-9]" );
        for( int i = 0; i < 3; ++i )
        {
            stdout.printf( @"-- source: $src\n" );
            src = regex.replace( src, -1, 0, "value" );
            stdout.printf( @"-- result: $src\n\n" );
        }
    }

    public static void main()
    {
        Test.run( "a INPUTX b" );
    }
}

I wrote this code based on the example in the docs. However, after compiling with valac Test.vala --pkg glib-2.0 and running, I get:

-- source: a INPUTX b
-- result: a INPUTX b

-- source: -- source: 
-- result: N�

-- source: -- source: 
-- result: PN�

What am I doing wrong?


Solution

  • After looking into the generated C code, I concluded that this rather is a Vala-related issue: Vala puts a g_free to the end of the loop's body, which frees the memory returned by g_regex_replace, and that is referenced by src. But why does Vala do that?

    The reason is that (see)

    arguments are, by default, unowned.

    Hence, when we assign the string object returned by regex.replace to the unowned string src, that reference is (see)

    not recorded in the object

    and the Vala compile considers it to be safe to dispose - although it's not quiet clear, why this happens particularly at the end of the loop's body.

    So the straiht-forward solution is to declare the src argument as owned.