사람들은 실수로 코드를 종료 (또는 중단)하는 경우 메모리를 확보 할 필요가 없다는 것을 이미 지적했습니다. 그러나 경우에 따라, 내가 개발 한 패턴이 있으며, 오류가 발생했을 때 자원을 만들고 찢어 버리기 위해 많이 사용합니다.참고 : 실제 코드를 작성하지 않고 여기에 패턴을 보여주고 있습니다.
int foo_create(foo_t *foo_out) {
int res;
foo_t foo;
bar_t bar;
baz_t baz;
res = bar_create(&bar);
if (res != 0)
goto fail_bar;
res = baz_create(&baz);
if (res != 0)
goto fail_baz;
foo = malloc(sizeof(foo_s));
if (foo == NULL)
goto fail_alloc;
foo->bar = bar;
foo->baz = baz;
etc. etc. you get the idea
*foo_out = foo;
return 0; /* meaning OK */
/* tear down stuff */
fail_alloc:
baz_destroy(baz);
fail_baz:
bar_destroy(bar);
fail_bar:
return res; /* propagate error code */
}
"나는 고토를 사용하기 때문에 나쁘다"라는 말을 몇 가지 가지게 될 것입니다. 그러나 일관되게 적용하면 코드를보다 명확하고 단순하며 유지 보수하기가 쉬워 지도록 goto를 체계적이고 체계적으로 사용합니다. 코드가 없으면 코드를 통해 문서화 된 간단한 경로를 얻을 수 없습니다.
실제 사용중인 상용 코드에서 이것을 보려면, 말하자면 arena.c from the MPS (동시에 메모리 관리 시스템)을보십시오.
이것은 가난한 사람의 시도 ... 마무리 처리기의 일종이며 소멸자와 비슷한 것을 제공합니다.
저는 이제 greybeard처럼 들릴 것입니다. 그러나 다른 사람들의 C 코드에서 수년 동안 일하면서 명확한 오류 경로가없는 것은 종종 매우 심각한 문제입니다. 특히 네트워크 코드 및 기타 신뢰할 수없는 상황에서 그렇습니다. 그 (것)들을 소개해서 때때로 저에게 상담 수입의 조금을 만들었다.
귀하의 질문에 대해 말할만한 다른 것들이 많이 있습니다. 유용 할 때를 대비하여이 패턴으로 남겨 두겠습니다.
exit()에 대한 일반 호출시 atexit() 함수를 사용하고 링크 된 목록에 할당 된 모든 메모리를 해제하는 함수 (이 경우 전역 변수 여야 함)를 작성할 수도 있습니다. 일반 exit()를 사용하지 않는 것을 기억해야합니다. –
하지만 왜? 운영 체제가 이미 할당 된 메모리 목록을 유지 관리하고 있습니다. 이 기능을 복제하면 약간의 자아 인플레이션 이외의 이점없이 종료 프로세스가 느려질 것입니다. 응용 프로그램을 MSDOS로 이식 할 계획이 아니라면 운영 체제에서 작업을 수행하십시오. – Eclipse
이유는 결국 규율과 funcitonality가 메모리 누수를 추적하는 데 도움이 될 것입니다. 코드를 올바르게 코딩하면 DEFINE 또는 MACRO 정의를 통해 끌 수 있습니다. – ojblass