왜 내가 같은 포인터를 선언 할 때() 무료 이용해야합니까 :포인터에서 자유롭지 만 일반 선언이 아닌 이유는 무엇입니까?
int *temp = (int*)malloc(sizeof(int))
*temp = 3;
하지만 내가 할 때
int temp = 3;
왜 내가 같은 포인터를 선언 할 때() 무료 이용해야합니까 :포인터에서 자유롭지 만 일반 선언이 아닌 이유는 무엇입니까?
int *temp = (int*)malloc(sizeof(int))
*temp = 3;
하지만 내가 할 때
int temp = 3;
정상 선언 스택에 배치됩니다. 함수가 반환 될 때 스택 포인터는 함수가 호출되기 전의 값으로 돌아가므로 메모리가 자동으로 회수됩니다.
Malloc 기반 선언은 '힙'에서 할당되므로 프로그래머가 할당 및 할당 해제를 관리해야합니다.
malloc로 선언 된 것만 큼 자유롭게 포인터를 사용할 필요는 없습니다. 또한 자동적으로 그 범위를 벗어나면 폐기 될 스택
int a = 3;
int* p = &a;
및 (포인터와 함께)이 메모리의 메모리 위치를 가리키는 포인터를 선언 할 수있다. malloc을 사용하면 힙에 같은 메모리가 할당되므로 수동으로 정리 작업을 처리해야합니다.
명확하게 설명하자면 : 포인터 분실은 스택에 만들어지고 그들은 힙에 할당 된 데이터에 대한 메모리 주소를 보유합니다. 스택은 32 비트 시스템에서 4 바이트를, 64 비트 시스템에서는 스택에서 8 바이트를 차지합니다. –
@ 브라이언 : 설명해 주셔서 고맙습니다. 내 편집으로 내 대답이 기술적으로 정확 해 졌다고 생각합니다. –
언어는 스택과 힙 사이를 선택합니다.
당신은 스택과 힙 사이에 선택하는 이유, 이유 : 당신은 당신의 코드 블록의 범위를지나 사용할 수 있도록 의도적으로 자신을 해제하지 않는 힙에
은 왜 힙이 자동으로 해제 할 수 없습니다 당신이 메모리를 완료하면 알 수있는 방법이 없습니다
때문입니다. 가비지 콜렉션을 에뮬레이트하는 방법이 있지만 스택에 더 이상 변수가없고 힙의 데이터에 대한 포인터를 보유하는 힙이있는 경우에 관련됩니다. 힙 대
스택에 더 :
C 언어의하자 당신이 스택 또는 힙에 변수를 정의 할 것인지 여부를 선택했다.
malloc은 힙에 변수를 만듭니다. int x와 같은 간단한 선언; 스택에 변수를 만듭니다.
See further reading on stack vs heap in my answer here.
포인터 :
그냥 명확히하기 : 포인터 한다거나 할 스택에 생성되고, 그들은 힙에 할당 된 데이터를 메모리 주소를 누르고 있습니다. 스택은 32 비트 시스템에서 4 바이트를, 64 비트 시스템에서는 스택에서 8 바이트를 차지합니다.
많은 사람들이 스택과 힙 할당의 차이점에 대해 대답하는 반면 매우 바람직한 질문인데, 근본적인 대답은 언더 레이 시스템이 여러분에게 뭔가를 노출해서는 안된다는 것입니다.
메모리를 할당 할 때 메모리를 할당 할 때 걱정하지 않아도됩니다. 시스템은 사용자가 더 이상 액세스 (포인트 또는 참조)가 없다는 것을 알기에 충분히 똑똑해야하므로 자동으로 메모리를 다시 사용할 수 있습니다.
Java 및 C#과 같은 최신 언어가이 작업을 수행했습니다.
이것은 논쟁의 여지가 있으며 질문에 대답하지 않는다.또한 언어의 나이와는 아무런 관련이 없습니다 (가비지 수집을 사용하는 오래된 언어의 예로서 Lisp을 참조하십시오). – rmeador
@rmeador - 나는 동의한다 –
나는 "당신이 기억을 할당 할 때, 당신이 그것을 돌려 줄 걱정할 필요가 없다"는 말은 매우 순진하다고 생각한다. 환경에 가비지 수집이 포함되어 있더라도 항상 되돌려 주어야한다고 걱정할 것입니다. –
더 이상 만든 점은 this post입니다.
알 니 탁이 정확합니다. 나는 "stack"이 실제로 무엇을 의미하는지 지적하고 싶습니다.
프로그램이 함수를 호출 할 때 함수는 일정량의 작업을 수행 한 다음 반환하고 다음 코드 행으로 계속 진행합니다. 이 함수는 함수가 완료 될 때 반환 할 위치를 알 수 없습니다. 따라서이 기계는 함수를 호출하기 전에 프로그램에서 다음 명령문의 주소를 푸시하는 데 사용되는 각 프로그램에 대한 호출 스택을 가지고 있습니다. "return"문은 프로그램 주소를 간단히 표시하고 점프합니다.
스택은 임시 공간의 편리한 스크래치 패드이기도합니다. 스택의 사용하지 않는 영역에 쓸 수 있습니다. C 함수 안에서 지역 변수를 선언하는 것은 정확히 이것을합니다. 함수가 반환 될 때 스택은 정리 공간을 확보하거나 해제하거나 다른 방법으로 처리 할 필요가 없습니다. 어쨌든 임시 공간 이었기 때문에 스택이 범위를 벗어납니다.
반대로 malloc()
을 호출하면 프로그램에 대한 메모리를 명시 적으로 설정하고 프로그램이 실행되는 동안 범위에 남아있는 힙에서 메모리를 할당합니다. 따라서 메모리가 free()
이 아니면 메모리가 할당 된 상태로 남게됩니다.
필요성은 포인터를 선언했는지 여부와 상관없이 malloc()
메모리를 사용했는지 여부에 달려 있습니다. 브라이언 본디처럼
int number
", "
char string[10]
", "
float your_boat
", 등) 다음 코드는 펑션 블록을 떠날 때와 같은 범위에서 떨어질 때 멀리 이동합니다. 따라서
free()
을 호출 할 때 질문의 포인터 ("
temp
")가 사라지지 않습니다.
malloc()
을 호출 할 때 할당 된 코드가 사라집니다. 포인터가 그대로 남아 있습니다. 즉, 예제 코드 바로 다음에 "
int *temp;
"을 말할 필요없이 "
temp = &some_other_variable
"이라고 말할 수 있습니다.
누군가가 이제까지 그들은 또한, 즉 프로그램,
메모리를 주장 것이며, 그 데이터는, 당신은
을 말할 수있을 것이라고 발표 할 것을 요구하지 않았다
malloc()
를 호출 할 일이 있다는 기능을 구현하는 경우
나중에
free(temp);
말을하지만이 구현되는 방식 malloc()
아니다없이
int * temp = (int*)malloc(sizeof(int));
.
C는 스택이나 힙에 대한 개념이 없다는 점에 유의해야합니다. 위의 응답은 99 %의 정확하고 정확한 통찰력을 제공합니다.
C 개체 세 저장 기간을 정의 정적, 자동 및 는 할당. (§6.2.4.1)
정적 개체 (예 : 전역 변수)는 전체 프로그램 기간 동안 사용할 수 있습니다.
자동 개체는 해당 변수가 범위 내에있는 한 존재합니다. 그들은 범위를 벗어나 자마자 존재를 멈 춥니 다.
두 가지 극단임을 유의하십시오. C는 사이에 포인트를줍니다 : 할당 된 개체입니다. (은 동적으로 할당 된 메모리입니다.) 은 개체의 시작과 끝을 컴퓨터에 알려줍니다. 그리고 이것은 표준 함수 malloc() (또는 파생 상품) 및 free()을 사용하여 수행됩니다.
엄밀히 말하자면, 은이어야합니다. 은 무료입니다 (). 아니면 당신이 할 수 있습니다 (당신은 이것에 대한 정식 표준을 읽어야 할 것입니다)하지만, 프로그램이 종료되기 바로 전에 의 메인() 끝에 그것을 모두 할 수 있습니다. 또는 운영체제에 남겨두면됩니다 (대부분은 아니지만 대부분). 그러나 다시 말하자면 - 으로 전화하면 객체가 생깁니다. malloc(), 프로그램이 종료 될 때 밖으로 나가십시오. 종료됩니다.
여기서 실질적인 영향에 대해 자세히 이야기 할 필요는 없습니다. 메모리는 유한합니다. 메모리가 부족해지기 전에 너무 많은 바이트 만 할당 할 수 있습니다. static 개체를 사용하면 모든 것이 낭비됩니다. 덩어리 또는 하나의 큰 덩어리 인 메모리를 재사용하려고 시도하면 어떤 경우에도 동적 할당 방식과 유사합니다. 을 사용하면 수명이 긴 오브젝트에 대해 스토리지를 사용하면 가능한 한 큰 범위가되도록합니다. 어쨌든 정적 오브젝트에 해당합니다.
- 이제
, 몇 가지 메모 : temp
여기에 자동 객체입니다
{
int *temp = malloc(sizeof(int));
*temp = 5;
//free(temp);
}
참고.범위로 끝나기 만하면 끝납니다.} 그러나 객체 은을 가리키고 있습니다. 그 주소에 free()를 부를 때까지 존재할 것입니다. temp
에는 그 주소의 유일한 복사본이 있기 때문에 temp
이 범위를 벗어나면 free()를 호출 할 기회가 손실됩니다. 일부 메모리는 영구적으로 할당되지만 아직 사용할 수 없습니다. 이를 메모리 누수이라고합니다.
가비지 수집은 객체 저장을 관리하는 또 다른 방법입니다. } 상기
{
int *temp = gc_malloc(sizeof(int));
*temp = 5;
}
경우 컴퓨터가 할당 된 개체에 대한 마지막 참조, temp
가 손실 된 것을 결정할 것이며, 그것을 해제하는 것은 좋은 생각이 될 것이라고 : C의 구현처럼 보일 수 있습니다.
무료() 객체 (간단한 예제가 생각할 수있는 작은 사안이 아닌)에 대해 걱정할 필요가없는 트레이드 오프이지만 gc_malloc()은 간단한 malloc()과 temp
이 범위를 벗어나는 곳에서 보이지 않는 코드가 실행됩니다. 그리고 컴퓨터가 temp
이 마지막 참조 였다고 결정할 수있는 완전히 다른 주제입니다. (실제적인 해결책으로는 "int * temp"주위에 더 많은 코드를 작성해야 할 수도 있습니다.)
이것은 전역 적으로 선언 된 변수에도 적용됩니까? – samoz
아니요, AFAICR 전역 적으로 선언 된 변수는 응용 프로그램의 알려진 저장소 요구 사항에 따라 O/S가 별도로 설정하는 별도의 메모리 블록 인 "데이터 세그먼트"에 공백이 있습니다. – Alnitak
전역 변수는 모듈을 포함하는 모듈이 언로드되거나 프로세스가 종료 될 때 "해제"됩니다. – Michael