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



我不确定我是否滥用了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: $srcn" );
            src = regex.replace( src, -1, 0, "value" );
            stdout.printf( @"-- result: $srcnn" );
        }
    }
    public static void main()
    {
        Test.run( "a INPUTX b" );
    }
}

我根据文档中的示例编写了此代码。但是,在使用valac Test.vala --pkg glib-2.0编译并运行之后,我得到:

-- source: a INPUTX b
-- result: a INPUTX b
-- source: -- source: 
-- result: N�
-- source: -- source: 
-- result: PN�

我做错了什么?

在查看生成的C代码后,我得出结论,这是一个与Vala相关的问题:Vala将g_free放在循环体的末尾,这将释放由g_regex_replace返回的内存,并由src引用。但瓦拉为什么要这么做呢?

原因是(见)

默认情况下,

参数是无主的。

因此,当我们将regex.replace返回的string对象赋值给unowned string src时,该引用是(参见)

未记录在对象

和Vala编译器认为它可以安全处理——尽管不太清楚为什么会发生这种情况,特别是在循环体的末尾。

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

考虑以下(无意义的)代码:

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: $srcn" );
        //src = regex.replace( src, -1, 0, "value" );
        src = foo (src);
        stdout.printf( @"-- result: $srcnn" );
    }
}
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 ()

我闻到某个地方有bug(要么在编译器中,要么在vapi中),但我不确定。

相关内容

  • 没有找到相关文章

最新更新