Vala 字符串处理会破坏内存。为什么以及如何避免?
Vala string processing corrupts memory. Why and how to avoid?
我不确定我是在滥用 Vala 还是在滥用 GLib.Regex
,因为我对两者都不熟悉。我创建了一个最小示例,它重现了错误。从下面的代码中,我希望它打印 a INPUTX b
六次,并交替使用 source
和 result
作为前缀:
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�
我做错了什么?
考虑这个(废话)代码:
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 中),但我不确定。
查看生成的 C 代码后,我得出结论,这是一个与 Vala 相关的问题:Vala 将 g_free
放到循环体的末尾,这释放了 [=11 返回的内存=],并由 src
引用。但瓦拉为什么要这么做?
原因是(see)
arguments are, by default, unowned.
因此,当我们将 regex.replace
返回的 string
对象分配给 unowned string src
时,该引用是 (see)
not recorded in the object
并且 Vala 编译器认为它可以安全处理 - 尽管还不是很清楚,为什么这种情况特别发生在循环体的末尾。
所以直接的解决方案是将 src
参数声明为 owned
。
我不确定我是在滥用 Vala 还是在滥用 GLib.Regex
,因为我对两者都不熟悉。我创建了一个最小示例,它重现了错误。从下面的代码中,我希望它打印 a INPUTX b
六次,并交替使用 source
和 result
作为前缀:
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�
我做错了什么?
考虑这个(废话)代码:
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 中),但我不确定。
查看生成的 C 代码后,我得出结论,这是一个与 Vala 相关的问题:Vala 将 g_free
放到循环体的末尾,这释放了 [=11 返回的内存=],并由 src
引用。但瓦拉为什么要这么做?
原因是(see)
arguments are, by default, unowned.
因此,当我们将 regex.replace
返回的 string
对象分配给 unowned string src
时,该引用是 (see)
not recorded in the object
并且 Vala 编译器认为它可以安全处理 - 尽管还不是很清楚,为什么这种情况特别发生在循环体的末尾。
所以直接的解决方案是将 src
参数声明为 owned
。