컴파일러가 할당 해제를 자동으로 삽입하지 않는 이유는 무엇입니까?


63

C와 같은 언어에서는 프로그래머가 무료로 통화를 삽입해야합니다. 왜 컴파일러가 이것을 자동으로하지 않습니까? 인간은 합리적인 시간 (버그 무시)으로 처리하므로 불가능하지 않습니다.

편집 : 참고로, 여기에 흥미로운 예제가 다른 토론입니다.


125
그리고 이것이 바로 우리가 여러분에게 계산 성 이론을 가르치는 이유입니다. ;)
Raphael

7
인간이 모든 경우를 결정할 수 없기 때문에 이것은 계산 문제가 아닙니다. 완전성 문제입니다. 할당 취소 문에는 분석에 배포 환경 및 C 소스 코드에 포함되지 않은 예상 작업에 대한 정보가 포함되어 있지 않으면 분석을 통해 완전히 복구 할 수없는 정보가 포함됩니다.
Nat

41
아니요, 계산 문제입니다. 주어진 메모리 조각을 할당 해제해야하는지 여부 를 결정할 수 없습니다. 고정 프로그램의 경우 사용자 입력 또는 기타 외부 간섭이 없습니다.
Andrej Bauer

1
의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 . 질문을 구체적으로 다루지 않는 모든 의견 과 개선 방법 은 즉시 삭제됩니다.
Raphael

2
@BorisTreukhov, 대화방으로 가져 가세요. 안드레이가 탈출 분석이 "불가능하다"고 말하지는 않는다 (이 맥락에서 그것이 의미하는 바를 정확히 결정하는 것은 나에게는 불분명하다). 완벽하게 정확한 탈출 분석 결정할 수 없습니다. 모두에게 : 대화방으로 가져 가십시오 . 질문을 개선하기위한 의견 만 여기에 게시하십시오. 다른 토론 및 의견은 대화방에 게시해야합니다.
DW

답변:


80

프로그램이 메모리를 다시 사용할지 여부를 결정할 수 없기 때문입니다. 이것은 free()모든 경우 에 호출 할 때 알고리즘을 정확하게 결정할 수 없다는 것을 의미합니다. 이는이 작업을 시도한 컴파일러가 메모리 누수가있는 일부 프로그램 및 / 또는 해제 된 메모리를 계속 사용하는 일부 프로그램을 생성해야 함을 의미합니다. 컴파일러가 두 번째 작업을 수행하지 않았고 프로그래머가 free()버그를 수정하기 위해 호출을 삽입하도록 허용 free()하더라도 해당 컴파일러 를 호출 하는 시간을 아는 free()것은 시도하지 않은 컴파일러를 사용할 때 호출하는 시간을 아는 것보다 훨씬 어렵습니다. 도와주세요.


12
우리는 결정 불가능한 문제를 해결하는 인간의 능력을 다루는 질문이 있습니다 . 컴파일러가 사용하는 알고리즘에 따라 잘못 컴파일되는 프로그램의 예를 보여줄 수 없습니다. 그러나 모든 알고리즘은 무한히 많은 다른 프로그램에 대해 잘못된 출력을 생성합니다.
David Richerby

1
의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Gilles

2
여러분, 채팅 하세요. 답변 자체와 직접 관련 이없는 모든 내용 과 개선 방법은 삭제됩니다.
Raphael

2
컴파일러가 행복하게하는 많은 일들은 일반적으로 결정 불가능합니다. 라이스 정리에 항상 굴복한다면 컴파일러 세계의 어느 곳도 가지 못할 것입니다.
Tikhon Jelvis

3
이것은 관련이 없습니다. 모든 컴파일러에 대해 결정 불가능한 경우 모든 사람에게도 결정 불가능합니다. 그러나 우리는 인간이 free()올바르게 삽입하기를 기대 합니다.
Paul Draper

53

David Richerby가 올바르게 지적했듯이 문제는 일반적으로 결정할 수 없습니다. 객체 라이브 니스는 프로그램의 글로벌 속성이며 일반적으로 프로그램의 입력에 따라 달라질 수 있습니다.

정확한 동적 가비지 수집 조차도 결정 불가능한 문제입니다! 모든 실제 가비지 수집기는 도달 가능성을 나중에 할당 된 개체가 필요한지 여부에 대한 보수적 인 근사값으로 사용합니다. 근사치이지만 근사치입니다.

그러나 그것은 일반적으로 사실입니다. 컴퓨터 과학 사업에서 가장 악명 높은 경찰 중 하나는 "일반적으로 불가능하기 때문에 우리는 아무것도 할 수 없습니다"입니다. 반대로, 진로를 만들 수있는 경우가 많이 있습니다.

참조 카운팅에 기반한 구현은 "컴파일러 삽입 해제"와 매우 유사하여 차이를 말하기가 어렵습니다. LLVM자동 참조 카운팅 ( Objective-CSwift에서 사용 )이 유명한 예입니다.

지역 유추컴파일 타임 가비지 수집 은 현재 활발한 연구 분야입니다. MLMercury 와 같은 선언적 언어 에서는 객체를 만든 후에 수정할 수없는 훨씬 쉬운 것으로 판명되었습니다 .

이제 인간 주제에 대해 인간이 할당 수명을 수동으로 관리하는 세 가지 주요 방법이 있습니다.

  1. 프로그램과 문제를 이해함으로써. 예를 들어 사람은 수명이 비슷한 객체를 동일한 할당 객체에 넣을 수 있습니다. 컴파일러와 가비지 수집기는이를 유추해야하지만 사람은보다 정확한 정보를 가지고 있습니다.
  2. 필요한 경우에만 비 로컬 부기 (예 : 참조 횟수) 또는 기타 특수 할당 기술 (예 : 구역)을 선택적으로 사용합니다. 다시 말하지만, 인간은 이것을 컴파일러가 추론해야하는 곳에서 이것을 알 수 있습니다.
  3. 심하게. 결국 누수가 느린 실제 배포 된 프로그램에 대해서는 누구나 알고 있습니다. 그렇지 않은 경우, 때때로 프로그램 및 내부 API를 메모리 수명을 기준으로 재구성하여 재사용 성과 모듈성을 줄여야합니다.

의견은 확장 토론을위한 것이 아닙니다. 선언적 기능과 기능적 기능에 대해 논의하려면 채팅에서 수행하십시오 .
Gilles

2
이것은 질문에 대한 가장 좋은 답변입니다 (너무 많은 답변도 다루지 않습니다). 당신은에 한스 뵘의 선구적인 작업에 대한 참조를 추가 할 수 conseervative GC를 : en.wikipedia.org/wiki/Boehm_garbage_collector을 . 또 다른 흥미로운 점은 데이터 의미 (또는 확장 된 의미에서 유용성)가 추상 의미 또는 실행 모델과 관련하여 정의 될 수 있다는 것입니다. 그러나 주제는 정말 넓습니다.
babou

29

결정 불가능 문제가 아닌 불완전 성 문제

할당 해제 문의 최적 배치가 결정 불가능하다는 것은 사실이지만 여기서는 문제가되지 않습니다. 사람과 컴파일러 모두에게 결정할 수 없기 때문에 수동 프로세스인지 자동 프로세스인지에 관계없이 항상 최적의 할당 해제 배치를 선택하는 것은 불가능합니다. 그리고 완벽한 사람은 아무도 없기 때문에, 충분히 진보 된 컴파일러는 인간이 대략 최적의 배치를 추측 할 때 성능을 능가 할 수 있어야합니다. 따라서 결정 불가능 성이 명시 적 할당 해제 문이 필요한 이유는 아닙니다 .

외부 지식이 할당 해제 명세서 배치를 알려주는 경우가 있습니다. 그런 다음 해당 명령문을 제거하는 것은 운영 로직의 일부를 제거하는 것과 동일하며 컴파일러에게 해당 로직을 자동으로 생성하도록 요청하는 것은 생각하는 것을 추측하도록 요청하는 것과 같습니다.

예를 들어, REPL (Read-Evaluate-Print-Loop)을 작성한다고 가정합니다 . 사용자가 명령을 입력하면 프로그램이이를 실행합니다. 사용자는 REPL에 명령을 입력하여 메모리를 할당 / 할당 할 수 있습니다. 소스 코드는 사용자가 명령을 입력 할 때 할당 해제를 포함하여 가능한 모든 사용자 명령에 대해 REPL이 수행 할 작업을 지정합니다.

그러나 C 소스 코드가 할당 취소를위한 명시 적 명령을 제공하지 않으면 컴파일러는 사용자가 REPL에 적절한 명령을 입력 할 때 할당 해제를 수행해야한다고 유추해야합니다. 이 명령이 "할당 해제", "무료"또는 다른 것입니까? 컴파일러는 원하는 명령을 알 수있는 방법이 없습니다. 해당 명령 단어를 찾기 위해 논리로 프로그래밍하고 REPL이 찾더라도 컴파일러는 소스 코드에서 명시 적으로 지시하지 않는 한 할당 취소로 명령에 응답해야한다는 것을 알 수 없습니다.

tl; dr 문제는 C 소스 코드가 컴파일러에 외부 지식을 제공하지 않는다는 것입니다. 프로세스가 수 동인지 자동인지 여부에 따라 결정 불가능 성이 문제가되지 않습니다.


3
의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 . 이 답변의 단점을 구체적으로 다루지 않는 모든 추가 의견 과 해결 방법 은 즉시 삭제됩니다.
Raphael

23

현재 게시 된 답변 중 완전히 정확한 답변은 없습니다.

컴파일러가 할당 해제를 자동으로 삽입하지 않는 이유는 무엇입니까?

  1. 일부는 그렇습니다. (나중에 설명하겠습니다.)

  2. 사소하게, free()프로그램이 종료되기 직전에 호출 할 수 있습니다 . 그러나 귀하의 질문 free()에는 가능한 한 빨리 전화해야 할 필요가 있습니다.

  3. free()메모리에 도달 할 수없는 즉시 C 프로그램을 언제 호출 해야하는지에 대한 문제는 결정 불가능합니다. 이 문제와 임의의 다른 프로그램의 결정 불가능한 사항은 Halting Problem 에서 증명할 수 있습니다 .

  4. 결정 불가능한 문제는 컴파일러이든 인간이든 알고리즘에 의해 유한 한 시간 안에 항상 해결 될 수는 없습니다.

  5. 인간은 ( 그들 자신의) 알고리즘에 의해 메모리 정확성을 검증 할 수 있는 C 프로그램 의 서브셋 을 작성하려고한다 .

  6. 일부 언어는 # 5를 컴파일러에 빌드하여 # 1을 달성합니다. 메모리 할당을 임의로 사용하는 프로그램은 허용하지 않고 결정 가능한 하위 세트를 허용합니다. FothRust 는 C보다 메모리 제한이 더 많은 언어의 두 가지 예입니다. malloc()(1) 프로그램이 결정 가능한 세트 외부에 쓰여지는지를 감지 할 수 있습니다. (2) 인서트 할당 해제를 자동으로 수행합니다.


1
Rust가 어떻게하는지 이해합니다. 그러나 나는 이것을 한 Forth에 대해 들어 본 적이 없습니다. 정교하게 할 수 있습니까?
Milton Silva

2
@MiltonSilva, Forth-최소한 가장 기본적인 원래 구현은 힙이 아닌 스택 만 있습니다. 컴파일러가 쉽게 할 수있는 작업 인 콜 스택 포인터를 이동 / 할당 할 수있게합니다. Forth는 매우 간단한 하드웨어를 대상으로했으며 때로는 동적이지 않은 메모리 만 있으면됩니다. 사소하지 않은 프로그램에는 실제로 실행 가능한 솔루션이 아닙니다.
Paul Draper

10

"인간은 그렇게하므로 불가능하지 않다"는 잘 알려진 오류입니다. 우리는 우리가 창출 한 것을 이해하는 것만으로 (독립적으로 통제 할 필요는 없음) 돈이 일반적인 예입니다. 우리는 특히 인적 요소가없는 것처럼 보이는 기술적 문제에서 성공 가능성을 과대 평가하는 경향이 있습니다 (때로는 극적으로).

컴퓨터 프로그래밍에서 인간의 성과는 매우 열악 하며, 컴퓨터 과학에 대한 연구 (많은 전문 교육 프로그램이 부족함)는 왜이 문제가 간단한 해결책이 없는지 이해하는 데 도움이됩니다. 우리는 언젠가는 그리 멀지 않은 직장에서 인공 지능으로 대체 될 수 있습니다. 그럼에도 불구하고 항상 자동으로 할당 해제를 수행하는 일반적인 알고리즘은 없습니다.


1
인간의 오류에 대한 전제를 받아들이면서도 인간이 만든 사고 기계가 여전히 완벽 하지 않다고 가정한다는 것은 잘 알려져 있지 않지만 더 흥미 롭습니다. 행동이 진행될 수있는 유일한 가정은 인간의 마음이 완벽하게 계산할 가능성있다는 것입니다.
와일드 카드

1. 나는 생각하는 기계가 완전하지 않다고 말한 적이 없다. 인간보다 더 나은 것은 많은 경우에 이미 존재하는 것입니다. 2. 행동의 전제 조건으로서의 완전성 (심지어 잠재 성)에 대한 기대는 부조리하다.
André Souza Lemos 님

"우리는 언젠가는 그리 멀지 않은 곳에 직업에 대한 인공 지능으로 대체 될 수있다." 이것은 특히 말이되지 않습니다. 인간은 시스템의 의도의 원천입니다. 인간이 없으면 시스템의 목적 이 없습니다 . "인공 지능"이 정의 될 수 apparency 기계에 의해 지능형 현재의 시간 결정, 과거에 프로그래머 나 시스템 설계자의 현명한 결정에 의해 사실에 대해 가져왔다. 유지 보수가없는 경우 ( 개인이 수행 해야 함) AI (또는 검사되지 않고 완전 자동으로 남아있는 시스템)는 실패합니다.
와일드 카드

기계와 마찬가지로 인간의 의도는 항상 외부 에서 나옵니다 .
André Souza Lemos

완전히 사실이 아닙니다. (또한 "외부"는 소스를 정의하지 않습니다 . ) 의도가 실제로 존재하지 않는다는 의도를 나타내거나 의도가 존재하지만 어느 곳에서도 나오지 않는다고 진술합니다. 의도와 상관없이 의도가 존재할 수 있다고 생각하십니까? 어떤 경우에는 "의도"라는 단어를 오해합니다. 어느 쪽이든, 직접 시연하면이 주제에 대한 당신의 마음이 곧 바뀔 것입니다. 나는이 말을 한 단어만으로는 "의도"에 대한 이해를 이끌어 낼 수 없기 때문에이 글을 그만 둘 것이므로 여기서 더 논의하는 것은 의미가 없습니다.
와일드 카드

9

자동 메모리 관리 부족은 언어의 특징입니다.

C는 소프트웨어를 쉽게 작성할 수있는 도구가 아닙니다. 컴퓨터가 지시 한대로 무엇이든 할 수 있도록하는 도구입니다. 여기에는 선택한 순간에 메모리 할당 및 할당 해제가 포함됩니다. C는 컴퓨터를 정확하게 제어하려는 경우 또는 언어 / 표준 라이브러리 디자이너가 예상 한 것과 다른 방식으로 작업하려는 경우 사용하는 저수준 언어입니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
DW

2
이것이 (CS 부분) 질문에 어떻게 대답합니까?
Raphael

6
@Raphael Computer Science가 모호한 기술적 답변을 찾아야한다는 의미는 아닙니다. 컴파일러는 일반적인 경우 불가능한 많은 작업을 수행합니다. 자동 메모리 관리를 원하는 경우 여러 가지 방법으로 구현할 수 있습니다. C는 그렇게하지 않아야하기 때문에 그렇게하지 않습니다.
Jouni Sirén

9

문제는 대부분 역사적인 유물이며 구현이 불가능합니다.

대부분의 C 컴파일러가 코드를 작성하는 방식은 컴파일러가 한 번에 각 소스 파일 만 볼 수 있도록하는 것입니다. 전체 프로그램을 한 번에 보지 못합니다. 하나의 소스 파일이 다른 소스 파일이나 라이브러리에서 함수를 호출 할 때 모든 컴파일러는 함수의 실제 코드가 아니라 함수의 리턴 유형을 가진 헤더 파일을 보게됩니다. 이는 포인터를 반환하는 함수가있을 때 컴파일러가 포인터가 가리키는 메모리를 해제해야하는지 여부를 알 수있는 방법이 없습니다. 결정하는 정보는 해당 시점에 컴파일러에 표시되지 않습니다. 반면에 인간 프로그래머는 포인터로 수행해야 할 작업을 찾기 위해 함수의 소스 코드 나 설명서를 자유롭게 찾을 수 있습니다.

C ++ 11 또는 Rust와 같은 최신 저수준 언어를 살펴보면 포인터 유형에서 메모리 소유권을 명시 적으로 지정하여 문제를 대부분 해결했음을 알 수 있습니다. C ++에서는 unique_ptr<T>평문 대신 T*메모리를 보유 unique_ptr<T>하고 평문과 달리 객체가 범위의 끝에 도달하면 메모리가 해제되도록합니다 T*. 프로그래머는 메모리를 한 메모리에서 unique_ptr<T>다른 메모리로 넘길 수 있지만 unique_ptr<T>메모리를 가리키는 메모리는 항상있을 수 있습니다 . 따라서 누가 메모리를 소유하고 언제 해제해야하는지 명확하게 알 수 있습니다.

이전 버전과의 호환성을 위해 C ++은 여전히 ​​오래된 스타일의 수동 메모리 관리를 허용하므로 버그 보호 또는 보호 방법을 우회 할 수 unique_ptr<T>있습니다. Rust는 컴파일러 오류를 통해 메모리 소유권 규칙을 적용한다는 점에서 더욱 엄격합니다.

결정 불가능 성, 정지 문제 등은 그렇습니다. C 의미를 고수하면 메모리를 비워야 할 때 모든 프로그램을 결정할 수 없습니다. 그러나 학업이나 버그가있는 소프트웨어가 아닌 대부분의 실제 프로그램의 경우, 언제 무료로 제공해야하는지 아닌지를 결정하는 것이 절대적으로 가능합니다. 그것은 인간이 처음에 언제 자유를 얻을 수 있는지 아닌지를 알아낼 수있는 유일한 이유입니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Raphael

6

다른 답변은 가비지 수집을 수행 할 수 있는지 여부, 수행 방법에 대한 세부 정보 및 일부 문제에 중점을 두었습니다.

아직 다루어지지 않은 한 가지 문제는 가비지 수집에서 불가피한 지연입니다. C에서 프로그래머가 free ()를 호출하면 해당 메모리를 즉시 재사용 할 수 있습니다. (적어도 이론상!) 따라서 프로그래머는 100MB 구조를 해제하고 1 밀리 초 후에 다른 100MB 구조를 할당하며 전체 메모리 사용량이 동일하게 유지 될 것으로 예상 할 수 있습니다.

가비지 수집에는 적용되지 않습니다. 가비지 수집 시스템은 사용하지 않는 메모리를 힙으로 반환하는 데 약간의 지연이 있으며 이는 중요 할 수 있습니다. 100MB 구조가 범위를 벗어나고 밀리 초 후에 프로그램이 다른 100MB 구조를 설정하면 시스템이 단기간 동안 200MB를 사용한다고 합리적으로 예상 할 수 있습니다. "단기"는 시스템에 따라 밀리 초 또는 초일 수 있지만 여전히 지연이 있습니다.

RAM과 가상 메모리가 많은 PC에서 실행중인 경우에는이 사실을 눈치 채지 못할 것입니다. 그래도 리소스가 제한된 시스템 (예 : 임베디드 시스템 또는 전화)에서 실행중인 경우이를 진지하게 고려해야합니다. 이것은 단지 이론적 인 것이 아닙니다-개인적으로 .NET Compact Framework를 사용하고 C #에서 개발할 때 WinCE 시스템에서 작업 할 때 (장치 종류의 충돌과 같은) 문제를 일으키는 것을 보았습니다.


이론적으로 모든 할당 전에 GC를 실행할 수 있습니다.
adrianN

4
@adrianN 그러나 실제로 이것은 정신적이기 때문에 수행되지 않습니다. Graham의 요점은 여전히 ​​유효합니다. GC는 런타임 또는 필요한 잉여 메모리 측면에서 항상 상당한 오버 헤드가 발생합니다. 이 저울을 극단적으로 조정할 수 있지만 근본적으로 오버 헤드를 제거 할 수는 없습니다.
Konrad Rudolph

메모리가 확보 될 때 "지연"은 자원이 제한된 시스템보다 가상 메모리 시스템에서 더 큰 문제입니다. 전자의 경우, 시스템에 200MB의 여유 공간이 있어도 프로그램이 200MB보다 100MB를 사용하는 것이 더 나을 있지만, 후자의 경우 지연 시간이 좀 더 수용 가능하지 않으면 GC를 필요한 것보다 빨리 실행하는 이점이 없습니다. 다른 것보다 코드의 일부.
supercat

이것이 (CS 부분) 질문에 어떻게 대답하려고 시도하는지 알 수 없습니다.
Raphael

1
@Raphael 저는 가비지 수집의 원리로 잘 알려진 문제에 대해 설명했습니다. 이는 가비지 수집의 기본 단점 중 하나로서 CS에서 가르쳐야합니다. 나는 이것이 실제적으로 이론적 인 문제가 아님을 보여주기 위해 이것을 실제로 경험 한 개인적인 경험을했다. 이것에 대해 이해하지 못하면 주제에 대한 지식을 향상시키기 위해 기꺼이 이야기 해 드리겠습니다.
Graham

4

문제는 할당 해제가 프로그래머가 소스 코드의 다른 부분에서 추론해야하는 것으로 가정합니다. 그렇지 않습니다. "프로그램에서이 시점에서 메모리 참조 FOO는 더 이상 유용하지 않습니다" (프로시 저럴 언어로) 할당 해제 명령문으로 인코딩 될 때까지 프로그래머의 마음에 알려진 정보 입니다.

이론적으로 다른 코드 줄과 다르지 않습니다. 컴파일러가 자동으로 "프로그램에서이 시점에서 레지스터 BAR 입력을 확인하십시오" 또는 "기능 호출이 0이 아닌 경우 현재 서브 루틴 종료 "를 삽입하지 않는 이유는 무엇 입니까? 컴파일러의 관점에서 볼 때 이유는 이 답변에 표시된 "불완전 성" 입니다. 그러나 프로그래머가 아는 모든 것을 말하지 않으면 모든 프로그램이 불완전하게 고통받습니다.

실생활에서 거래 취소는 거친 작업이나 상용구입니다. 우리의 두뇌는 그것들을 자동으로 채우고 그것에 대해 중얼 거린다. "컴파일러는 그것을 더 잘하거나 더 잘 할 수있다"는 정서는 사실이다. 그러나 이론적으로는 다른 언어가 우리에게 더 많은 이론을 선택할 수 있지만 실제로는 그렇지 않습니다.


4
" '이 시점에서 메모리 참조 FOO는 더 이상 유용하지 않다'는 것은 프로그래머에게만 알려진 정보입니다."-분명히 틀 렸습니다. a) 많은 FOO의 경우, 값 의미론을 갖는 지역 변수와 같이 이것을 알아내는 것은 사소한 일입니다. b) 당신은 프로그래머가 이것을 항상 알고 있다고 제안합니다. 이것은 분명히 지나치게 낙관적 인 가정입니다. 그것이 사실이라면, 우리는 메모리 처리 불량으로 인한 심각한 버그가 보안에 중요한 소프트웨어가 아닙니다. 아아, 우리는.
Raphael

나는 프로그래머 FOO가 더 이상 유용하지 않다는 것을 알기 위해 언어가 설계되었다고 제안하고 있습니다 . 나는 이것이 사실이 아니라는 점에 분명히 동의하며, 따라서 정적 분석 및 / 또는 가비지 수집이 필요합니다. 만세, 우리는. 그러나 영업 이익의 문제는, 그 일이있을 때 하지 손으로 코딩 deallocs만큼 가치?
트래비스 윌슨

4

무슨 일이 됩니다 가비지 콜렉션이있어, 참조 카운팅 (목표 - C, 스위프트)를 사용하여 컴파일러이 있습니다 다. 참조 횟수를 계산하는 사람은 강한 참조주기를 피함으로써 프로그래머의 도움이 필요합니다.

실제 에 응답 전 그 컴파일러 작가가 충분하고 컴파일러가 사용할 수 있도록 충분히 빠른 방법을 알아 내지 못했다은 "왜". 컴파일러 작성자는 일반적으로 매우 영리하기 때문에 충분하고 빠른 방법을 찾기가 매우 어렵다고 결론 내릴 수 있습니다.

그것이 매우 어렵다는 이유 중 하나는 물론 그것이 결정 불가능하기 때문입니다. 컴퓨터 과학에서 "결정 성"에 대해 이야기 할 때 "올바른 결정을 내린다"는 의미입니다. 물론 인간 프로그래머는 올바른 결정에 국한되지 않기 때문에 메모리 할당을 해제 할 위치를 쉽게 결정할 수 있습니다 . 그리고 그들은 종종 잘못된 결정을 내립니다.


나는 여기에 기여를 보지 못했습니다.
babou

3

C와 같은 언어에서는 프로그래머가 무료로 통화를 삽입해야합니다. 왜 컴파일러가 이것을 자동으로하지 않습니까?

메모리 블록의 수명은 컴파일러의 결정이 아니라 프로그래머의 결정이기 때문입니다.

그게 다야. 이것은 C의 디자인입니다. 컴파일러는 메모리 블록 할당의 의도를 알 수 없습니다. 인간은 모든 메모리 블록의 목적을 알고 있기 때문에이 목적을 달성 할 수 있으므로 해방 할 수 있습니다. 그것은 작성되는 프로그램 디자인의 일부입니다.

C는 저수준 언어이므로 메모리 블록을 다른 프로세스 나 다른 프로세서로 전달하는 인스턴스는 매우 빈번합니다. 극단적 인 경우 프로그래머는 의도적으로 메모리 청크를 할당하고 시스템의 다른 부분에 메모리 압력을 가하기 위해 다시는 사용하지 않을 수 있습니다. 컴파일러는 블록이 여전히 필요한지 알 수 없습니다.


-1

C와 같은 언어에서는 프로그래머가 무료로 통화를 삽입해야합니다. 왜 컴파일러가 이것을 자동으로하지 않습니까?

C와 다른 많은 언어들에서, 컴파일 시점에 분명해야하는 경우에 컴파일러가 이와 동등한 기능을 수행 할 수있는 기능이 있습니다 : 자동 지속 변수 (즉, 일반적인 지역 변수)의 사용 . 컴파일러는 이러한 변수를위한 충분한 공간을 마련하고 (정의 된) 수명이 다했을 때 해당 공간을 해제해야합니다.

C99 이후 가변 길이 배열은 C 기능이므로 자동 지속 시간 개체는 원칙적으로 계산 가능한 지속 시간의 동적 할당 개체가 수행하는 C의 거의 모든 기능을 제공합니다. 실제로 C 구현 은 VLA 사용에 실질적인 제한을 둘 수 있습니다. 즉, 스택에 할당되어 크기가 제한 될 수 있습니다. 그러나 이는 언어 설계 고려 사항이 아니라 구현 고려 사항입니다.

의도 된 사용법으로 자동 지속 시간을 제공하지 못하는 객체는 정확하게 컴파일 타임에 수명을 결정할 수없는 객체입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.