Vala字符串处理会破坏内存。为什么以及如何避免?

时间:2016-08-11 10:41:54

标签: glib vala memory-corruption

我不确定我是否误用了Vala或GLib.Regex,因为我对两者都不熟悉。我创建了一个最小的例子,它可以重现错误。从以下代码中,我希望它会打印a INPUTX b六次,以sourceresult为前缀:

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" );
    }
}

我根据the example in the docs编写了此代码。但是,在使用valac Test.vala --pkg glib-2.0进行编译并运行后,我得到:

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

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

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

我做错了什么?

2 个答案:

答案 0 :(得分:1)

在查看生成的C代码之后,我得出结论,这与Vala相关的问题是:Vala将g_free置于循环体的末尾,从而释放g_regex_replace返回的内存。 {1}},由src引用。但是为什么Vala这样做呢?

原因是(see

  

默认情况下,参数是无主的。

因此,当我们将string返回的regex.replace对象分配给unowned string src时,该引用为(see

  

未记录在对象

并且Vala编译认为处理是安全的 - 尽管它并不安静,为什么这种情况尤其发生在循环体的末端。

因此,直接解决方案是将src参数声明为owned

答案 1 :(得分:0)

考虑这个(废话)代码:

string foo (string s)
{
    return s;
}

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" );
        src = foo (src);
        stdout.printf( @"-- result: $src\n\n" );
    }
}

void main ()
{
    run( "a INPUTX b" );
}

Vala编译器(理所当然地)抱怨:

test.vala:13.2-13.16: error: Invalid assignment from owned expression to unowned variable
        src = foo (src);
        ^^^^^^^^^^^^^^^

因此vapi文件的方法必须有不同之处,因为它允许调用Regex.replace ()

我在某处(在编译器或vapi中)闻到了一个错误,但我不确定。