창고 구역 과 창고 구역 의 메모리 분배 의 차 이 를 간단히 분석 하 다.

5740 단어 쌓다창고.
지금까지 이 문제 에 대한 인식 이 비교적 몽롱 했다.나 는 많은 친구 들 도 마찬가지 라 고 믿는다.항상 메모리 가 창고 에서 분배 되 고 또 쌓 여 분배 되 는 것 을 들 었 다.그러면 그들 사이 에는 도대체 어떤 차이 가 있 을 까?이 문 제 를 설명 하기 위해 서,우 리 는 먼저 메모리 내부 의 조직 상황 을 살 펴 보 자.

위의 그림 에서 알 수 있 듯 이 프로그램 이 사용 하 는 메모리 가 다음 과 같은 몇 부분 으로 나 뉘 어 져 있다.
1.스 택 구역(stack)은 컴 파일 러 에 의 해 자동 으로 분 배 됩 니 다.함수 의 매개 변수 값,부분 변수의 값 등 을 저장 합 니 다.메모리 의 분 배 는 연속 적 입 니 다.평소에 우리 가 말 한 스 택 과 유사 합 니 다.아직 잘 모 르 면 배열 이 라 고 생각 합 니 다.메모리 분 배 는 연속 적 으로 분 배 됩 니 다.즉,분 배 된 메모리 가 연속 적 인 메모리 구역 에 있 습 니 다.우리 가 변 수 를 설명 할 때,그러면 컴 파일 러 는 현재 스 택 의 끝 을 자동 으로 이어서 메모 리 를 분배 합 니 다.
2.쌓 기 영역(heap)은 일반적으로 프로그래머 가 분배 하여 방출 합 니 다.만약 에 프로그래머 가 방출 하지 않 으 면 프로그램 이 끝 날 때 운영 체제 에서 회수 할 수 있 습 니 다.링크 와 같이 메모리 의 분 포 는 연속 적 인 것 이 아니 라 서로 다른 지역 의 메모리 블록 이 지침 을 통 해 연 결 됩 니 다.특정한 노드 가 체인 에서 끊 어 지면 우 리 는 인위적으로 끊 어 진 노드 를 메모리 에서 방출 해 야 합 니 다.
3.전역 구역(정적 구역)(static)전역 변수 와 정적 변수의 저장 소 는 한 곳 에 놓 여 있 습 니 다.초기 화 된 전역 변수 와 정적 변 수 는 한 지역 에 있 습 니 다.초기 화 되 지 않 은 전역 변수 와 초기 화 되 지 않 은 정적 변 수 는 인접 한 다른 지역 에 있 습 니 다.프로그램 종료 후 시스템 에서 방출
4.문자 상수 구역 상수 문자열 은 여기에 놓 여 있 습 니 다.프로그램 종료 후 시스템 에서 방출
5.프로그램 코드 구역 에 함수 체 의 바 이 너 리 코드 를 저장 합 니 다.
예 를 들 어.char c;/창고 에 char*p=new char[3];/쌓 아 올 리 고 주 소 를 p 에 부여 합 니 다.
컴 파일 러 가 첫 번 째 명령 을 만 났 을 때 크기 를 계산 한 다음 에 현재 스 택 의 공간 이 필요 한 공간 크기 보다 크다 는 것 을 찾 습 니 다.만약 에 이때 스 택 안의 공간 이 신청 한 공간 보다 크 면 메모리 공간 을 분배 합 니 다.주의:여기 서 내부 공간의 분 배 는 연속 적 입 니 다.마지막 분배 가 끝 난 후에 분 배 됩 니 다.만약 에 창고 안의 공간 이 신청 한 공간 크기 보다 작 으 면 시스템 은 창고 가 넘 치 는 것 을 밝 히 고 해당 하 는 이상 정 보 를 제공 합 니 다.
컴 파일 러 가 두 번 째 명령 을 만 났 을 때 p 는 스 택 에서 분 배 된 것 이기 때문에 p 에 내 적 공간 을 분배 할 때 위의 방법 과 같 지만 new 키 워드 를 만 났 을 때 컴 파일 러 는 모두 알 고 있 습 니 다.이것 은 사용자 가 신청 한 동적 메모리 공간 이기 때문에 쌓 아 올 려 서 공간 분 배 를 찾 습 니 다.여러분 은 쌓 아 놓 은 메모리 공간 이 연속 적 인 것 이 아니 라 는 것 을 주의 하 십시오.이것 은 해당 하 는 링크 가 그 공간 구역 의 내 적 블록 을 연결 하기 때문에 메모리 공간 을 분배 하 는 지정 을 받 은 후에 해당 하 는 공간 을 바로 분배 하지 않 고 필요 한 공간 을 계산 한 다음 에 전체 더미(즉 전체 체인 의 노드)에 여러 번 배열 해 야 한다.처음 만난 메모리 블록 을 할당 합 니 다.마지막 으로 더미 에 분 배 된 문자 배열 의 첫 주 소 를 p.에 부여 합 니 다.이 럴 때 p 에 현재 저장 되 어 있 는 것 은 더미 에서 신청 한 문자 배열 의 첫 번 째 주소 입 니 다.즉,더미 에서 신청 한 배열 의 주 소 는 현재 스 택 에서 신청 한 포인터 변수 p 에 부여 되 었 습 니 다.문 제 를 더욱 구체 적 으로 설명 하기 위해 서 입 니 다.아래 그림 을 보 세 요:
위의 그림 에서 보 듯 이 우 리 는 동적 으로 분 배 된 배열 의 첫 주 소 를 포인터 p 가 가리 키 는 내용 에 저장 했다.
주의:스 택 에서 신청 한 메모리 공간 은 우리 가 변수 가 있 는 역할 영역 을 나 온 후에 시스템 은 자동 으로 이 공간 을 회수 할 것 입 니 다.그리고 더미 에서 신청 한 공간 은 해당 하 는 역할 영역 이 나 온 후에 우 리 는 delete 를 명시 적 으로 호출 하여 신청 한 메모리 공간 을 방출 해 야 합 니 다.만약 에 우리 가 이 공간 을 제때에 방출 하지 않 으 면그러면 메모리 에 있 는 메모리 조각 이 점점 많아 지고 우리 의 실제 메모리 공간 도 점점 적어 집 니 다.즉,고립 된 메모리 블록 이 점점 많아 집 니 다.여기 서 우 리 는 쌓 여 있 는 메모리 구역 이 연속 적 이지 않 은 지,아니면 효과 적 인 메모리 구역 을 체인 포인터 로 연결 하 는 지 알 고 있 습 니 다.만약 에 우리 가 특정한 메모리 에 신청 하면...그러면 이 메모리 구역 은 연속 적 인(링크 를 통 해 연 결 된)메모리 블록 에서 끊 어 집 니 다.만약 에 우리 가 사용 한 후에 제때에 방출 하지 않 으 면 고립 됩 니 다.포인터 가 가리 키 지 않 기 때문에 이 구역 은 메모리 조각 이 될 것 입 니 다.그래서 동적 으로 분 배 된 메모리(NEW 신청 을 통 해)를 사용 한 후에반드시 명시 적 으로 DELETE 를 삭제 해 야 합 니 다.이 점 에 대해 서 는 반드시 기억 해 야 합 니 다.
위 에서 여러분 에 게 그들 간 의 개념 을 진 술 했 습 니 다.그들 두 사람의 사용 비교 에 있어 저 는 여러분 들 이 끊임없이 진술 할 수 없습니다.이 문제 에 대해 인터넷 한 네티즌 의 글 에서 비교적 상세 하 게 논술 하고 전문 적 인 색 채 를 덧 붙 였 습 니 다.아래 의 글 은 단편 적 입 니 다.
신청 크기 의 제한 스 택:Windows 에서 스 택 은 낮은 주소 로 확 장 된 데이터 구조 로 연속 적 인 메모리 영역 입 니 다.이 말 은 스 택 꼭대기 의 주소 와 스 택 의 최대 용량 은 시스템 이 미리 정 해 놓 은 것 이 고,WINDOWS 에서 스 택 의 크기 는 2M(1M 라 고도 하 는데,한 번 컴 파일 할 때 정 해진 상수)이 며,신청 한 공간 이 스 택 의 남 은 공간 을 초과 할 경우 overflow 를 알려 준 다 는 뜻 이다.따라서 스 택 에서 얻 을 수 있 는 공간 이 적다.
더미:더 미 는 높 은 주소 로 확 장 된 데이터 구조 로 불 연속 메모리 영역 입 니 다.이것 은 시스템 이 링크 로 저 장 된 남 은 메모리 주소 이기 때문에 자 연 스 럽 게 연속 되 지 않 고 링크 의 이동 방향 은 낮은 주소 에서 높 은 주소 로 이동 합 니 다.쌓 인 크기 는 컴퓨터 시스템 의 효과 적 인 가상 메모리 에 제한 을 받는다.이 를 통 해 알 수 있 듯 이 쌓 아 올 린 공간 이 비교적 유연 하고 크다.
신청 효율 비교:스 택 은 시스템 에서 자동 으로 분배 되 고 속도 가 비교적 빠르다.하지만 프로그래머 는 통제 할 수 없다.
더 미 는 new 에서 분 배 된 메모리 로 보통 속도 가 느 리 고 메모리 조각 이 생기 기 쉬 우 나 사용 하기에 가장 편리 합 니 다.
또한,WINDOWS 에서 가장 좋 은 방법 은 VirtualAlloc 로 메모 리 를 분배 하 는 것 입 니 다.그 는 쌓 고 있 는 것 도 아니 고 스 택 에서 프로 세 스 의 주소 공간 에 직접 메모 리 를 보관 하 는 것 도 아 닙 니 다.사용 하기에 가장 불편 하지만.하지만 속도 가 빠 르 고 유연 하 다.
스 택 에 저 장 된 콘 텐 츠 스 택:함수 가 호출 될 때 첫 번 째 로 스 택 에 들 어간 것 은 주 함수 의 다음 명령(함수 호출 문장의 다음 실행 가능 한 문장)의 주소 이 고 그 다음 에 함수 의 각 매개 변수 입 니 다.대부분의 C 컴 파일 러 에서 매개 변 수 는 오른쪽 에서 왼쪽으로 스 택 에 들 어간 다음 함수 의 부분 변수 입 니 다.정적 변 수 는 스 택 에 들 어가 지 않 습 니 다.
이번 함수 호출 이 끝 난 후에 부분 변 수 는 먼저 스 택 에서 나 온 다음 에 매개 변수 입 니 다.마지막 으로 스 택 상단 지침 은 처음에 저 장 된 주 소 를 가리 키 고 있 습 니 다.즉,주 함수 중의 다음 명령 입 니 다.프로그램 은 이 점 에서 계속 실 행 됩 니 다.
더미:보통 쌓 인 머리 에 바이트 로 쌓 인 크기 입 니 다.쌓 여 있 는 구체 적 인 내용 은 프로그래머 의 안배 가 있다.
액세스 효율 비교 char s1[]=char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaa 는 실행 시간 에 값 을 부여 합 니 다.bbbbbbbbbbbb 는 컴 파일 할 때 확 정 됩 니 다.그러나 이후 액세스 에 서 는 포인터 가 가리 키 는 문자열(예 를 들 어 쌓 기)보다 스 택 에 있 는 배열 이 빠 릅 니 다.
예 를 들 어

void main()
{
    char a = 1;
    char c[] = "1234567890";
    char *p ="1234567890";
    a = c[1];
   a = p[1];
    return;
}
에 대응 하 는 어 셈 블 리 코드

10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
첫 번 째 는 읽 을 때 문자열 의 요 소 를 레지스터 cl 에 직접 읽 고 두 번 째 는 먼저 지침 값 을 ex 에 읽 어야 하 며 ex 에 따라 문 자 를 읽 으 면 느 려 집 니 다.
소결:쌓 기와 창고 의 차 이 는 다음 과 같은 비유 로 알 수 있다.창 고 를 사용 하 는 것 은 우리 가 식당 에 가서 밥 을 먹 는 것 처럼 주문(신청),돈 지불,먹 기(사용)만 하고 배 부 르 면 간다.채 소 를 썰 거나 채 소 를 씻 는 등 준비 작업 과 설거지,솥 을 씻 는 등 마무리 작업 에 신경 쓸 필요 가 없다.그의 장점 은 빠 르 지만 자유도 가 적다.
더 미 를 사용 하 는 것 은 마치 자신 이 좋아 하 는 요 리 를 만 드 는 것 처럼 비교적 번 거 롭 지만 자신의 입맛 에 비교적 부합 되 고 자유도 가 있다.

좋은 웹페이지 즐겨찾기