[an error occurred while processing this directive]
[an error occurred while processing this directive]void do_f(){ struct A *a; struct B *b; struct C *c; a = create_a(); b = create_b(); c = create_c(); f(a,b,c); free_c(c); free_b(b); free_a(a); }create_a() は中で malloc() を呼んで、初期化を行い、a のアドレスを返します。 ただし初期化でエラーが発生すると、NULL を返します。
void do_f(){ struct A *a; struct B *b; struct C *c; a = create_a(); if(a == NULL) return; b = create_b(); if(b == NULL){ free_a(a); return; } c = create_c(); if(c == NULL){ free_b(b); free_a(a); return; } f(a,b,c); free_c(c); free_b(b); free_a(a); }意味的には OK ですが、free_a() を色んなところに書かないといけなかったりして、あまりきれいではありません。
void do_f(){ struct A *a; struct B *b; struct C *c; a = create_a(); if(a == NULL) return; b = create_b(); if(b == NULL) goto free_a; c = create_c(); if(c == NULL) goto free_c; f(a,b,c); free_c(c); free_b: free_b(b); free_a: free_a(a); }goto を使うことで、かえってコピペの少ない、きれいなコードになっています。 資源の確保と解放が逆順になっているのがポイント。
void do_f(){ struct A *a = NULL; struct B *b = NULL; struct C *c = NULL; do { a = create_a(); if(a == NULL) break; b = create_b(); if(b == NULL) break; c = create_c(); if(c == NULL) break; f(a,b,c); } while(0); if(c) free_c(c); if(b) free_b(b); if(a) free_a(a); }ループのようですが、while の条件が 0 (偽)なので、実は一回しか実行されません。