diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index c9fd9efb82..c391c79eab 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1325,6 +1325,13 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { ast.MatchExpr { return_type = it.return_type } else {} } + // Free the old value assigned to this string var (only if it's `str = [new value]`) + if g.pref.autofree && assign_stmt.op == .assign && assign_stmt.left_types.len == 1 && + assign_stmt.left_types[0] == table.string_type && assign_stmt.left[0] is ast.Ident { + g.write('string_free(&') + g.expr(assign_stmt.left[0]) + g.writeln('); // free str on re-assignment') + } // json_test failed w/o this check if return_type != table.void_type && return_type != 0 { sym := g.table.get_type_symbol(return_type) diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 1ce138d115..b262244bd6 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -308,6 +308,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { g.or_block(tmp_opt, node.or_block, node.return_type) if is_gen_or_and_assign_rhs { g.write('\n$cur_line$tmp_opt') + // g.insert_before_stmt('\n /* VVV */ $tmp_opt') } } } @@ -544,10 +545,12 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { t := '_tt${g.tmp_count2}_arg_expr_${fn_name}_$i' g.called_fn_name = name str_expr := g.write_expr_to_string(arg.expr) - // g.insert_before_stmt('string $t = $str_expr; // new. to free $i ') + g.insert_before_stmt('string $t = $str_expr; // new3. to free $i ') + /* cur_line = g.go_before_stmt(0) // println('cur line ="$cur_line"') g.writeln('string $t = $str_expr; // new. to free $i ') + */ } } // Handle `print(x)` diff --git a/vlib/v/tests/valgrind/1.strings_and_arrays.v b/vlib/v/tests/valgrind/1.strings_and_arrays.v index 435e6c86ac..a25d1e2d68 100644 --- a/vlib/v/tests/valgrind/1.strings_and_arrays.v +++ b/vlib/v/tests/valgrind/1.strings_and_arrays.v @@ -49,6 +49,11 @@ fn str_replace() { println(r) } +fn reassign_str() { + mut s := 'a' + 'b' + s = 'x' + 'y' // 'a' + 'b' must be freed before the re-assignment +} + fn match_expr() string { x := 2 res := match x { @@ -76,6 +81,7 @@ fn main() { str_tmp_expr() str_inter() match_expr() + reassign_str() // str_replace() println('end') }