[vala] Fix memory leak when freeing arrays of structs
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] Fix memory leak when freeing arrays of structs
- Date: Sat, 1 Aug 2009 18:07:17 +0000 (UTC)
commit 87b90ea71c7c07f18715972266cf881c69bc6f13
Author: Jürg Billeter <j bitron ch>
Date: Sat Aug 1 20:06:32 2009 +0200
Fix memory leak when freeing arrays of structs
Fixes bug 589144.
codegen/valaccodearraymodule.vala | 53 +++++++++++++++++++++++++++++++++++++
codegen/valaccodebasemodule.vala | 21 ++++++++++----
2 files changed, 68 insertions(+), 6 deletions(-)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index fbc17a6..4137a94 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -378,6 +378,59 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule {
}
}
+ private CCodeForStatement get_struct_array_free_loop (Struct st) {
+ var cbody = new CCodeBlock ();
+ var cptrarray = new CCodeIdentifier ("array");
+ var cea = new CCodeElementAccess (cptrarray, new CCodeIdentifier ("i"));
+
+ var cfreecall = new CCodeFunctionCall (get_destroy_func_expression (new StructValueType (st)));
+ cfreecall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cea));
+
+ var cforcond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("array_length"));
+ cbody.add_statement (new CCodeExpressionStatement (cfreecall));
+
+ var cfor = new CCodeForStatement (cforcond, cbody);
+ cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
+ cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("i"), new CCodeConstant ("1"))));
+
+ return cfor;
+ }
+
+ public override string? append_struct_array_free (Struct st) {
+ string cname = "_vala_%s_array_free".printf (st.get_cname ());;
+
+ if (source_declarations.add_declaration (cname)) {
+ return cname;
+ }
+
+ var fun = new CCodeFunction (cname, "void");
+ fun.modifiers = CCodeModifiers.STATIC;
+ fun.add_parameter (new CCodeFormalParameter ("array", "%s*".printf (st.get_cname ())));
+ fun.add_parameter (new CCodeFormalParameter ("array_length", "gint"));
+ source_declarations.add_type_member_declaration (fun.copy ());
+
+ var cdofree = new CCodeBlock ();
+
+ var citdecl = new CCodeDeclaration ("int");
+ citdecl.add_declarator (new CCodeVariableDeclarator ("i"));
+ cdofree.add_statement (citdecl);
+
+ cdofree.add_statement (get_struct_array_free_loop (st));
+
+ var ccondarr = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("array"), new CCodeConstant ("NULL"));
+ var cif = new CCodeIfStatement (ccondarr, cdofree);
+ fun.block = new CCodeBlock ();
+ fun.block.add_statement (cif);
+
+ var carrfree = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
+ carrfree.add_argument (new CCodeIdentifier ("array"));
+ fun.block.add_statement (new CCodeExpressionStatement (carrfree));
+
+ source_type_member_definition.append (fun);
+
+ return cname;
+ }
+
private CCodeForStatement get_vala_array_free_loop () {
var cbody = new CCodeBlock ();
var cptrarray = new CCodeCastExpression (new CCodeIdentifier ("array"), "gpointer*");
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index ca28952..3351119 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2106,6 +2106,10 @@ internal class Vala.CCodeBaseModule : CCodeModule {
return destroy_func;
}
+ public virtual string? append_struct_array_free (Struct st) {
+ return null;
+ }
+
public virtual CCodeExpression get_unref_expression (CCodeExpression cvar, DataType type, Expression expr) {
var ccall = new CCodeFunctionCall (get_destroy_func_expression (type));
@@ -2159,9 +2163,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
ccall.add_argument (new CCodeConstant ("TRUE"));
} else if (type is ArrayType) {
var array_type = (ArrayType) type;
- if (array_type.element_type.data_type == null || array_type.element_type.data_type.is_reference_type ()) {
- requires_array_free = true;
-
+ if (requires_destroy (array_type.element_type)) {
CCodeExpression csizeexpr = null;
bool first = true;
for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -2173,9 +2175,16 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
}
- ccall.call = new CCodeIdentifier ("_vala_array_free");
- ccall.add_argument (csizeexpr);
- ccall.add_argument (new CCodeCastExpression (get_destroy_func_expression (array_type.element_type), "GDestroyNotify"));
+ var st = array_type.element_type.data_type as Struct;
+ if (st != null && !array_type.element_type.nullable) {
+ ccall.call = new CCodeIdentifier (append_struct_array_free (st));
+ ccall.add_argument (csizeexpr);
+ } else {
+ requires_array_free = true;
+ ccall.call = new CCodeIdentifier ("_vala_array_free");
+ ccall.add_argument (csizeexpr);
+ ccall.add_argument (new CCodeCastExpression (get_destroy_func_expression (array_type.element_type), "GDestroyNotify"));
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]