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().
This commit is contained in:
Bi-Ruei, Chiu 2016-11-09 00:17:25 +08:00
parent 0bfcefc368
commit b9adfc5f91
4 changed files with 12 additions and 0 deletions

View File

@ -330,6 +330,8 @@ main(int ac, char **av) {
exit(EX_SOFTWARE); exit(EX_SOFTWARE);
} }
asn1p_delete(asn);
return 0; return 0;
} }

View File

@ -22,6 +22,7 @@ asn1p_expr_new(int _lineno, asn1p_module_t *mod) {
expr->spec_index = -1; expr->spec_index = -1;
expr->module = mod; expr->module = mod;
expr->_lineno = _lineno; expr->_lineno = _lineno;
expr->ref_cnt = 0;
} }
return expr; return expr;
@ -235,6 +236,12 @@ asn1p_expr_free(asn1p_expr_t *expr) {
if(expr) { if(expr) {
asn1p_expr_t *tm; asn1p_expr_t *tm;
if (expr->ref_cnt) {
/* Decrease reference count only */
expr->ref_cnt--;
return;
}
/* Remove all children */ /* Remove all children */
while((tm = TQ_REMOVE(&(expr->members), next))) { while((tm = TQ_REMOVE(&(expr->members), next))) {
if(tm->parent_expr != expr) if(tm->parent_expr != expr)

View File

@ -216,6 +216,7 @@ typedef struct asn1p_expr_s {
asn1p_value_t *default_value; /* For EM_DEFAULT case */ asn1p_value_t *default_value; /* For EM_DEFAULT case */
} marker; } marker;
int unique; /* UNIQUE */ int unique; /* UNIQUE */
int ref_cnt; /* reference count */
/* /*
* Whether automatic tagging may be applied for subtypes. * Whether automatic tagging may be applied for subtypes.

View File

@ -138,6 +138,7 @@ asn1p_value_fromtype(asn1p_expr_t *expr) {
if(v) { if(v) {
v->value.v_type = expr; v->value.v_type = expr;
v->type = ATV_TYPE; v->type = ATV_TYPE;
expr->ref_cnt++;
} }
return v; return v;
} }
@ -258,6 +259,7 @@ asn1p_value_free(asn1p_value_t *v) {
asn1p_value_free(v->value.choice_identifier.value); asn1p_value_free(v->value.choice_identifier.value);
break; break;
} }
memset(v, 0, sizeof(*v));
free(v); free(v);
} }
} }