programing

C에서 변수 선언을 해제(삭제)하는 방법은?

starjava 2023. 10. 4. 20:29
반응형

C에서 변수 선언을 해제(삭제)하는 방법은?

매크로의 경우와 같습니다.

#undef SOMEMACRO 

우리가 메모리를 많이 절약할 수 있도록 C의 변수도 언클레어하거나 삭제할 수 있습니까?

에 있습니다.malloc()그리고.free()할 경우, printf("%d", a);다를 .

test.c:4:14: error: ‘a’ undeclared (first use in this function)

아니요, 하지만 범위가 종료되면 모든 범위 로컬 변수가 제거되므로 이를 달성하기 위해 작은 최소 범위를 만들 수 있습니다.이와 같은 것:

void foo() {
    // some codes
    // ...
    {    // create an extra minimum scope where a is needed
        int a;
    }
    // a doesn't exist here
}

질문에 대한 직접적인 답은 아니지만, 이 질문에 적절한 답이 없는 이유와 C에서 변수를 삭제하는 것이 불가능한 이유에 대한 순서와 이해를 가져올 수 있습니다.

점 #1 변수란 무엇입니까?

변수는 프로그래머가 메모리 공간에 이름을 할당하는 방법입니다.이것은 변수가 실제 공간을 차지할 필요가 없다는 것을 의미하기 때문에 중요합니다.컴파일러가 문제의 메모리를 추적할 수 있는 방법이 있는 한, 정의된 변수는 공간을 전혀 차지하지 않도록 여러 가지 방식으로 번역될 수 있습니다. 사항:항:const int i = 10;다 할 수 .i즉각적인 가치로i이 경우 0개의 데이터 메모리를 차지하게 됩니다(아키텍처에 대한 depending는 코드 크기를 증가시킬 수 있습니다).또는 컴파일러는 값을 레지스터에 저장할 수 있으며 스택이나 힙 공간은 사용되지 않습니다.대부분 코드에 존재하며 반드시 런타임에 존재하지 않는 레이블을 "정의 해제"하는 것은 의미가 없습니다.

점 #2 변수는 어디에 저장됩니까?

포인트 #1 이후에는 논리를 깨지 않고 컴파일러가 원하는 것을 무엇이든 할 수 있기 때문에 이 질문이 쉽지 않다는 것을 이미 알고 있지만 일반적으로 변수는 스택에 저장됩니다.스택의 작동 방식은 질문에 매우 중요합니다.함수를 호출할 때 기계는 CPU의 명령 포인터와 현재 스택 포인터의 현재 위치를 가져와 스택에 밀어 넣으며 스택 포인터를 스택의 다음 위치로 대체합니다.그런 다음 호출되는 함수의 코드로 점프합니다.

이 함수는 자신이 가진 변수의 수와 필요한 공간을 파악하기 때문에 프레임 포인터를 움직여 함수의 모든 변수를 차지할 수 있는 프레임을 캡처한 다음 스택만 사용합니다.단순화하기 위해 함수는 처음부터 모든 변수에 대한 충분한 공간을 캡처하고 각 변수는 함수의 스택 프레임의 처음부터 잘 정의된 오프셋을 가집니다.*변수도 차례로 저장됩니다.이 작업 후에 프레임 포인터를 조작할 수는 있지만 비용이 너무 많이 들고 대부분 무의미합니다. 실행 중인 코드는 마지막 스택 프레임만 사용하고 필요한 경우 남은 스택을 모두 차지할 수 있으므로(스택은 스레드 시작 시 할당됨) "릴리즈" 변수는 거의 이점이 없습니다.스택 프레임 중간에서 변수를 해제하려면 조각 모음 작업이 필요하므로 CPU 비용이 많이 들고 몇 바이트의 메모리를 복구하는 데 무의미합니다.

요점 #3: 컴파일러가 제 역할을 하도록 하라.

여기서 마지막 문제는 컴파일러가 당신이 할 수 있는 것보다 당신의 프로그램을 더 잘 최적화할 수 있다는 간단한 사실입니다.컴파일러는 프로그램 메모리 소모(-O3 컴파일 플래그)를 줄이기 위해 동시에 접근할 수 없는 가변 범위와 중복 메모리를 검출할 수 있었습니다.어차피 컴파일러가 모르는 사이에 변수를 "방출"할 필요가 없기 때문입니다.

이것은 변수가 너무 작아서 중요하지 않다는 것과 당신이 요구한 것을 달성할 수 있는 메커니즘이 없다는 것에 대해 제 앞에서 말한 모든 것을 보완하기 위한 것입니다.


* 동적 크기의 배열을 지원하는 언어는 배열의 크기가 계산된 후에만 해당 배열에 대한 공간을 할당하도록 스택 프레임을 변경할 수 있습니다.

C나 대다수의 프로그래밍 언어에서, 확실히 내가 아는 모든 프로그래밍 언어에서 그렇게 할 수 있는 방법이 없습니다.

그리고 당신은 "많은 기억"을 저장하지 못할 것입니다.만약 당신이 그런 일을 한다면 당신이 절약할 기억의 양은 미미할 것입니다.아주 작아요 말할 가치도 없어요

이러한 방식으로 변수를 제거하는 데 용이한 메커니즘은 아마도 제거하는 변수보다 더 많은 메모리를 차지할 것입니다.

개별 변수의 코드를 재확보하는 코드의 호출은 변수 자체보다 더 많은 공간을 차지할 것입니다.

,purge()라의 하는 것.purge()입니다뿐만 아니라하고자 하는 더클 것입니다.int a; purge(a);purge()입니다보다 더 을 a그 자체.

왜냐하면 지금 말씀하시는 변수가 굉장히 작기 때문에. 그.printf("%d", a);다가 든 회수할 .int변수들.이 있다 할 수 있을 .그 방법이 있다고 해도 4바이트 정도는 절약할 수 있을 것입니다.이러한 변수들이 차지하는 메모리의 총 양은 극히 적습니다. 왜냐하면 이것은 프로그래머로서 얼마나 많은 변수들이 그들의 선언을 손으로 타이핑하여 선언하는지에 대한 직접적인 함수이기 때문입니다.몇입니다를 하기 전에 생각 없이 를 선언하는 것 않고 타자를 데 몇 입니다.int말할 만한 가치가 있는 메모리 양을 차지하는 변수들.

블록을 사용할 수 있습니다.{ }) 및 변수가 존재하는 범위를 제한하기 위해 변수를 가능한 한 늦게 정의합니다.

그러나 변수의 주소를 사용하지 않는 한, 컴파일러가 변수의 값을 유지해야 하는 범위를 결정하는 것은 큰 영향을 미치지 않기 때문에 생성된 코드에 전혀 영향을 미치지 않습니다.

변수의 주소를 사용하는 경우, 주로 별도의 컴파일과 같은 인라인 장벽이나 의미적 연결을 허용하는 것으로 인해 탈출 분석이 실패하면 컴파일러는 블록의 나중까지 해당 주소를 유지해야 한다고 가정할 수 있습니다.그것은 거의 중요하지 않습니다(몇 안 되는 것은 걱정하지 마십시오).int하는 몇 에 두는 .

스택에 저장된 메모리의 양이 너무 적으면 컴파일러의 세부 사항도 이해하고 싶을 것입니다.이것이 컴파일 할 때 어떤 역할을 하는지 알아내야 할 것입니다.스택-프레임의 실제 모양은 C 언어로 지정되지 않습니다.그것은 컴파일러가 알아서 할 일입니다.현재 승인된 답변의 예를 들어 보려면 다음과 같이 하십시오.

void foo() {
    // some codes
    // ...
    {    // create an extra minimum scope where a is needed
        int a;
    }
    // a doesn't exist here
}

이는 기능의 메모리 사용량에 영향을 줄 수도 있고 그렇지 않을 도 있습니다.gcc나 Visual Studio와 같은 메인스트림 컴파일러에서 이 작업을 수행하면 스택 크기가 아닌 속도에 최적화되므로 함수를 시작할 때 필요한 모든 스택 공간을 미리 할당할 수 있습니다.그들은 당신의 범위 분석과 가변적 사용 분석을 사용하여 필요한 최소한의 사전 할당을 파악하기 위한 분석을 수행할 것이지만, 그러한 알고리즘들은 말 그대로 추가 범위 분석의 영향을 받지 않을 것입니다.그들은 이미 그것보다 더 똑똑합니다.

다른 컴파일러들, 특히 임베디드 플랫폼용 컴파일러들은 스택 프레임을 다르게 할당할 수 있습니다.이러한 플랫폼에서는 이러한 범위 지정이 필요한 트릭일 수 있습니다.어떻게 차이를 구별할 수 있습니까?유일한 옵션은 다음과 같습니다.

  • 설명서 읽기
  • 시도해보고, 무엇이 효과가 있는지 확인해보세요.

또한 문제의 본질을 정확히 이해해야 합니다.저는 반품 값과 몇 가지를 제외한 모든 것에 대해 스택을 회피하는 특정 임베디드 프로젝트를 수행했습니다.int 말에 은 이 보다 더 제가 수석 개발자들에게 이런 어리석음에 대해 다그쳤을 때, 그들은 이 특정 애플리케이션에서 스택 공간은 전세계적으로 할당된 변수의 공간보다 더 중요하다고 설명했습니다.시스템이 의도한 대로 작동한다는 것을 증명하기 위해 거쳐야 하는 과정이 있었고, 모든 것을 미리 할당하고 재귀를 피할 수 있다면 이러한 과정은 훨씬 더 용이했습니다.당신이 해결하고자 하는 것의 정확한 성격을 먼저 알지 못하는 한, 당신은 결코 그런 복잡한 해결책에 도달하지 못할 것이라고 장담합니다.

또 다른 솔루션으로 항상 자신만의 스택 프레임을 구축할 수 있습니다.각 구조가 하나의 스택 프레임에 대한 변수를 포함하는 구조물 조합을 만듭니다.그럼 직접 추적해 보세요.다 같은 볼수.alloca할 수 한다면 ..

구조물의 결합이 효과가 있을까요?먹어봐.답은 컴파일러 의존적입니다.모든 변수가 특정 장치의 메모리에 저장되어 있으면 이 방법으로 스택 사용을 최소화할 수 있습니다.그러나 레지스터 컬러링 알고리즘을 상당히 혼란스럽게 하고 스택 사용량을 증가시킬 수 있습니다!그것이 당신에게 어떻게 되는지 확인해 보세요!

언급URL : https://stackoverflow.com/questions/45387465/how-to-undeclare-delete-variable-in-c

반응형