Free memory allocated in various functions

1. Add 'ref_cnt' field to asn1p_expr_t.
2. Initialize 'ref_cnt' field to zero when asn1p_expr_t is allocated.
3. Increase 'ref_cnt' field when asn1p_expr_t is cloned by asn1p_value_fromtype().
4. If 'ref_cnt' field of asn1p_expr_t is larger than zero, then asn1p_expr_free() only decrease its value.
5. Free memory pointed by fields of asn1p_expr_t and itself when 'ref_cnt' is zero and asn1p_expr_free() called.
6. Call asn1p_delete(asn) in main().
diff --git a/asn1c/asn1c.c b/asn1c/asn1c.c
index 8a6f785..2f5194c 100644
--- a/asn1c/asn1c.c
+++ b/asn1c/asn1c.c
@@ -330,6 +330,8 @@
         exit(EX_SOFTWARE);
     }
 
+    asn1p_delete(asn);
+
     return 0;
 }
 
diff --git a/libasn1parser/asn1p_expr.c b/libasn1parser/asn1p_expr.c
index b7a03ec..c2261e6 100644
--- a/libasn1parser/asn1p_expr.c
+++ b/libasn1parser/asn1p_expr.c
@@ -22,6 +22,7 @@
 		expr->spec_index = -1;
 		expr->module = mod;
 		expr->_lineno = _lineno;
+		expr->ref_cnt = 0;
 	}
 
 	return expr;
@@ -235,6 +236,12 @@
 	if(expr) {
 		asn1p_expr_t *tm;
 
+		if (expr->ref_cnt) {
+			/* Decrease reference count only */
+			expr->ref_cnt--;
+			return;
+		}
+
 		/* Remove all children */
 		while((tm = TQ_REMOVE(&(expr->members), next))) {
 			if(tm->parent_expr != expr)
diff --git a/libasn1parser/asn1p_expr.h b/libasn1parser/asn1p_expr.h
index 89d939a..dfeaa25 100644
--- a/libasn1parser/asn1p_expr.h
+++ b/libasn1parser/asn1p_expr.h
@@ -216,6 +216,7 @@
 		asn1p_value_t *default_value;	/* For EM_DEFAULT case */
 	} marker;
 	int unique;	/* UNIQUE */
+	int ref_cnt;	/* reference count */
 
 	/*
 	 * Whether automatic tagging may be applied for subtypes.
diff --git a/libasn1parser/asn1p_value.c b/libasn1parser/asn1p_value.c
index 63c80c7..0c89888 100644
--- a/libasn1parser/asn1p_value.c
+++ b/libasn1parser/asn1p_value.c
@@ -138,6 +138,7 @@
 	if(v) {
 		v->value.v_type = expr;
 		v->type = ATV_TYPE;
+		expr->ref_cnt++;
 	}
 	return v;
 }
@@ -258,6 +259,7 @@
 			asn1p_value_free(v->value.choice_identifier.value);
 			break;
 		}
+		memset(v, 0, sizeof(*v));
 		free(v);
 	}
 }