2012-08-14 2 views
2

제 질문은 4GB 주소 지정 시스템의 메모리 관리에 관한 것입니다
char *p = NULL;
메모리를 차지하나요?
그렇다면 힙 또는 스택의 위치와 양은 어느 정도입니까? 도 참조하십시오. char **p=NULL;char * p = NULL은 메모리를 사용합니까?

+0

'p'는 어디에 선언 되었습니까? 함수에서 로컬로? 기능 밖? – AnT

+0

@AndreyT는 어떤 차이가 있습니까? 그렇다면 둘 다 말해줘. – akash

답변

8

일반적인 32 비트 시스템에서 4 바이트가 소요됩니다.

예제가 일부 함수에서 지역 변수의 정의라고 가정하면 해당 바이트는 스택에서 가져옵니다. 비록 :

  • 변수가 다른 곳에서 사용되지 않으면 컴파일러는 생성 된 코드에서이 변수를 모두 제거 할 수 있습니다.
  • 변수가 로컬에서만 사용되고 그 주소가 사용되지 않으면 레지스터에 넣을 수 있으므로 "일반"메모리를 차지하지 않습니다.

대신, 그것은 (일반적이나, 정적 저장 기간의 변수) 전역 변수의 경우, 대부분의 시스템에서 스택과 소위 힙에서 분리 된 메모리의 특정 영역이 (있다)를 사용했습니다. 종종 copy-on-write 모드에서 실행 가능한 이미지에서 직접 매핑되는 메모리 영역 일뿐입니다. 그래서 여기서 4 바이트는이 특정 메모리 영역에서, 둘 다 실행 파일 안의 공간에서 점유됩니다.

char **p도 마찬가지입니다. 원칙적으로 어떤 이유로 든 더 크거나 다른 이유는 없습니다 (char *). char * p 또는 char ** p 집계 데이터 형식 (일반적으로 struct)의 일부라면 그런데


는, 그들이 걸릴 공간은 struct이 할당되는 곳에서 온다 - struct 변수가 지역 변수 인 경우, 그것을 스택에서 오는 경우, 힙에 malloc으로 동적으로 할당 된 경우 전역에 해당하는 경우 전역에 대한 특수 메모리 영역에서 온 것입니다. struct으로 촬영 한 공간에 대해 이야기하면서 패딩에 대한 추가 고려 사항이 적용됩니다.


"일반적인"32 비트 시스템에 대한 고려 사항입니다. 어떤 이상한 아키텍처가 char *과 크기가 다른 char **과 다른 것을 막을 수는 없습니다 (하지만 그 이유는 없습니다). 그래도 sizeof 연산자를 사용하여 직접 확인을 수행 할 수 있습니다.

표준에 관한 한, 포인터 크기에 부과 된 유일한 제약은 데이터 손실없이 void *에서 데이터로의 모든 포인터를 변환 할 수 있다는 것입니다 (실제로 표준에서는 스택 또는 레지스터). 또한 컴파일러는 "관찰 가능한 동작"이 표준에서 요청한 것과 일관된 한 원하는 모든 작업을 수행 할 수 있으므로 자세한 내용은 있지만 표준에서 요구하는 구현 세부 사항에 대한 실질적인 보장은 없습니다. 사용중인 컴파일러의 설명서에서 찾을 수 있습니다.

+0

그렇지 않으면 스택에 위치합니다. 'char ** p'와 동일합니다. – arrowd

+0

동적으로 할당 된'struct'에 멤버가 있다면 스택에 있습니까? –

+0

@BinaryWorrier : 동적으로 할당 된'struct' 멤버 일 수 없습니다. OP와 마찬가지로 직접 초기화 할 수 없기 때문입니다. –

1

변수가없는 경우 두 변수 버전 p은 일반적으로 각각 char*char**에 대한 메모리를 차지하며 자동 ("스택") 또는 정적 ("글로벌") 저장 장치입니다.필요한 크기는 void* (일반적으로 기계 단어 한 개)의 크기보다 크지 않습니다.

컴파일러는이 변수가 메모리에 저장되어있는 것처럼 "항상"동작 할 수 있지만 값을 직접 대체 할 수 있으면 변수를 완전히 제거 할 수 있습니다. 그러한 의미에서 C 구조가 어떤 특정한 구체적인 기계 코드가 될 것이라는 절대적인 보장은 없습니다.

0

포인터는 주소를 저장할 수있는 일반 변수 일뿐입니다. char * 변수가 만들어 질 때마다 변수의 값이 무엇이든 관계없이 메모리가 사용됩니다. 32 비트 시스템에서 포인터의 일반적인 크기는 32 비트이고 64 비트 컴퓨터에서는 64 비트입니다. int 또는 long처럼

관련 문제