最近、gnuCでクリーンアップ属性を使用してC ++でスマートポインターを実装する方法についての記事を読んでいます。
#define autofree __attribute__((cleanup(free_stack)))
__attribute__ ((always_inline))
inline void free_stack(void *ptr) {
free(*(void **) ptr);
}
そして例を使用して:
int main(void) {
autofree int *i = malloc(sizeof (int));
*i = 1;
return *i;
}
私の質問は次のとおりです。
パラメータをに渡す必要がないのはなぜfree_stack
ですか?
なぜfree(*(void **) ptr)
働くのですか?なぜそれがキャストされvoid**
、参照解除されるのかわかりません。
ここでは、この属性の定義は次のとおりです。
cleanup (cleanup_function)
変数がスコープ外になると、cleanup属性が関数を実行します。この属性は、自動関数スコープ変数にのみ適用できます。静的保存期間のあるパラメーターまたは変数には適用できません。関数は、変数と互換性のある型へのポインターという1つのパラメーターを取る必要があります。関数の戻り値(存在する場合)は無視されます。
にパラメータを渡す必要はありません。free_stack()
これは、自動変数がその変数へのポインタを引数としてスコープ外に出るたびに呼び出されるためです。
でメモリを割り当てmalloc()
ているので、解放する必要のあるポインタがあります。したがって、クリーンアップ関数に渡される引数は、実際にはポインター(またはvoid**
)(*(void**)ptr)
へのポインターであり、解放する必要のあるポインターに到達するために使用する必要があります。コードでi
は、スコープ外になると次のコードが実行されると考えることができます。
free_stack(&i);
更新:
クリーンアップ機能はメモリを解放することを意味しないことを覚えておいてください。それはクリーンアップを意味します。たとえば、次のクリーンアップ方法を使用して、スコープ外のときにファイルを閉じることができます。
#define autoclose __attribute__((cleanup(auto_close_file)))
__attribute__ ((always_inline))
inline void auto_close_file(void *ptr) {
fclose(*(FILE**) ptr);
}
int main(void) {
autoclose FILE *fp = fopen("test.txt", "w");
fputs("Hello World", fp);
return 0;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加