IT story

C 프로그램에서 fclose ()를 호출하지 않으면 어떻게됩니까?

hot-time 2020. 12. 30. 19:15
반응형

C 프로그램에서 fclose ()를 호출하지 않으면 어떻게됩니까?


첫째, fopen ()으로 파일을 열고 닫지 않는 것은 끔찍하게 무책임하고 잘못된 형식이라는 것을 알고 있습니다. 이건 호기심이 많으니 유머러스 해주세요 :)

C 프로그램이 많은 파일을 열고 닫지 않으면 결국 fopen ()이 실패하기 시작한다는 것을 알고 있습니다. 코드 외부에서 문제를 일으킬 수있는 다른 부작용이 있습니까? 예를 들어 파일 하나를 연 다음 닫지 않고 종료하는 프로그램이있는 경우 프로그램을 실행하는 사람에게 문제가 발생할 수 있습니까? 그러한 프로그램이 어떤 것이 (메모리, 파일 핸들) 누출됩니까? 프로그램이 종료 된 후 해당 파일에 다시 액세스하는 데 문제가있을 수 있습니까? 프로그램이 연속적으로 여러 번 실행되면 어떻게됩니까?


프로그램이 실행되는 동안 파일을 닫지 않고 계속 열면 프로세스에 사용할 수있는 파일 설명자 / 핸들이 부족하여 더 많은 파일을 열려고 시도하면 결국 실패하게됩니다. Windows에서는 기본적으로 다른 프로세스가 파일을 열 수 없도록하는 배타적 공유 모드로 파일이 열리기 때문에 다른 프로세스가 열어 놓은 파일을 열거 나 삭제하지 못하게 할 수도 있습니다.

프로그램이 종료되면 운영 체제가 정리됩니다. 프로세스를 종료 할 때 열어 둔 파일을 모두 닫고 필요한 다른 정리를 수행합니다 (예 : 파일이 닫을 때 삭제로 표시된 경우 파일을 삭제합니다. 그 종류는 플랫폼입니다. -특유한).

그러나주의해야 할 또 다른 문제는 버퍼링 된 데이터 입니다. 대부분의 파일 스트림은 데이터를 디스크에 쓰기 전에 메모리에 버퍼링합니다. FILE*stdio 라이브러리의 스트림을 사용하는 경우 두 가지 가능성이 있습니다.

  1. 프로그램은 exit(3)함수 를 호출 하거나 main(암시 적으로를 호출하는 exit(3)) 에서 복귀 하여 정상적으로 종료 되었습니다 .
  2. 프로그램이 비정상적으로 종료되었습니다. 이것은 호출 abort(3)또는 _Exit(3), 신호 / 예외 등으로 인해 죽을 수 있습니다 .

프로그램이 정상적으로 종료되면 C 런타임은 열려 있던 버퍼링 된 스트림을 플러시합니다. 따라서 FILE*플러시되지 않은 버퍼링 된 데이터가에 기록 된 경우 일반 종료시 플러시됩니다.

반대로 프로그램이 비정상적으로 종료되면 버퍼링 된 데이터는 플러시 되지 않습니다 . OS는 프로세스가 종료 될 때 "오, 당신은 파일 디스크립터를 열어 두었습니다. 프로그램이 디스크에 쓰려고했지만 그렇지 않은 메모리 어딘가에 임의의 데이터가 있다는 것을 알지 못합니다. 그러니 조심하세요.


C 표준은 호출 exit(또는에서 반환 main) 을 호출 하면 열려있는 모든 FILE객체가 fclose. 따라서 쓰기 오류를 감지 할 기회를 상실한다는 점을 제외하고는 완벽합니다.

편집 : 비정상 종료에 대한 보증은 없습니다 ( abort, 실패 assert, 기본 동작이 프로그램을 비정상적으로 종료하는 신호 수신-반드시 그러한 신호가 필요하지 않음에 유의하십시오-및 기타 구현 정의 수단). 다른 사람들이 말했듯이 최신 운영 체제는 개방형 OS 수준 파일 핸들과 같이 외부에서 볼 수있는 모든 리소스를 정리합니다 . 그러나이 경우 FILEs는 플러시 되지 않을 수 있습니다.

확실히 비정상 종료시 외부에서 볼 수있는 리소스를 정리하지 않은 OS가있었습니다. 당신이 그 경계가없는 경우는 "커널"및 / 또는 별개의 사용자 공간 "프로세스"와 "사용자"코드 사이에 하드 특권 경계를 시행하지와 함께 이동하는 경향이 단순히 그것을하지 않을 수 있기 때문에 있으므로 안전 할 모든 상황에서. (예를 들어, MS-DOS에서 열린 파일 테이블 위에 쓰레기를 쓰면 어떤 일이 발생하는지 생각해보십시오. 완벽하게 할 수 있습니다.)


제어하에 종료한다고 가정 exit()하거나 시스템 호출을 사용하거나에서 복귀 main()하면 열린 파일 스트림이 플러시 후 닫힙니다. C 표준 (및 POSIX)이이를 요구합니다.

당신이 등 제어 (코어 덤프, SIGKILL)을 종료하는 경우 사용하는 경우, 또는 _exit()또는_Exit() , 다음 열린 파일 스트림을 플러시되지 않습니다 (단, 파일 기술자는이 POSIX와 같은 파일 기술자와 시스템 가정, 폐쇄 끝 - 표준 C가하는 명령 파일 설명자가 아님). 참고 _Exit()C99 표준에 의해 의무화되어 있지만, _exit()POSIX에 의해 위임 (그러나 그들은 POSIX 시스템에서 동일하게 동작)입니다. 파일 설명자는 파일 스트림과 별개입니다. _exit()Unix에서 프로그램이 종료 될 때 어떤 일이 발생하는지 보려면 POSIX 페이지의 '프로그램 종료의 결과'에 대한 설명 을 참조하십시오.


프로세스가 종료되면 대부분의 최신 운영 체제 (특히 커널)는 모든 핸들과 할당 된 메모리를 해제합니다.

참조 URL : https://stackoverflow.com/questions/8175827/what-happens-if-i-dont-call-fclose-in-ac-program

반응형