C / C + + 더미, 창고 및 정적 데이터 구역 상세 설명

5 대 메모리 파 티 션
C + + 에서 메모 리 는 5 개의 구역 으로 나 뉘 는데 그들 은 각각 더미, 창고, 자유 저장 소, 전역 / 정적 저장 소 와 상수 저장 소 이다.
1. 스 택 은 컴 파일 러 가 필요 할 때 분배 되 고 필요 하지 않 을 때 자동 으로 명확 한 변수의 저장 소 입 니 다.안의 변 수 는 보통 국부 변수, 함수 매개 변수 등 이다.
2 더 미 는 new 에서 분 배 된 메모리 블록 입 니 다. 그들의 방출 컴 파일 러 는 관리 하지 않 고 우리 의 응용 프로그램 에서 제어 합 니 다. 보통 new 는 delete 에 대응 해 야 합 니 다.프로그래머 가 풀 어 주지 않 으 면 프로그램 이 끝나 면 운영 체제 가 자동 으로 회수 된다.
3. 자유 저장 소 는 malloc 등 으로 분 배 된 메모리 블록 입 니 다. 그 는 더미 와 매우 비슷 하지만 free 로 자신의 생명 을 끝 냅 니 다.
4 전역 / 정적 저장 소, 전역 변수 와 정적 변 수 는 같은 메모리 에 분 배 됩 니 다. 이전 C 언어 에서 전역 변 수 는 초기 화 되 지 않 은 것 과 초기 화 되 지 않 은 것 으로 나 뉘 었 습 니 다. C + + 에 서 는 이 구분 이 없 었 습 니 다. 그들 은 같은 메모리 영역 을 공동으로 사용 합 니 다.
5. 상수 저장 소 입 니 다. 이것 은 비교적 특수 한 저장 소 입 니 다. 그들 안에 저 장 된 것 은 상수 이 고 수정 을 허락 하지 않 습 니 다. (물론 정당 하지 않 은 수단 을 통 해 수정 할 수 있 고 방법 도 많 습 니 다)
 
더미 와 스 택 을 명 확 히 구분 하 다.
우선, 우 리 는 예 를 들 어:
 
void f() { int* p=new int[5]; } 

 
이 짧 은 한 마디 에 더미 와 스 택 이 포함 되 어 있 습 니 다. new 를 보면 우 리 는 먼저 생각 해 야 합 니 다. 우 리 는 메모리 한 개 를 분 배 했 습 니 다. 그러면 지침 p 는 요?그 가 할당 한 것 은 스 택 메모리 이기 때문에 이 말 은 스 택 메모리 에 메모리 더 미 를 가리 키 는 포인터 p 를 저장 한 다 는 뜻 이다.프로그램 에서 메모리 의 크기 를 확인 한 다음 operator new 로 메모 리 를 할당 한 다음 에 이 메모리 의 첫 번 째 주 소 를 되 돌려 스 택 에 넣 습 니 다. 그 는 VC6 에서 의 어 셈 블 리 코드 는 다음 과 같 습 니 다.
쓰다
00401028 push 14h
0040102A call operator new (00401060)
0040102F add esp,4
00401032 mov dword ptr [ebp-8],eax
00401035 mov eax,dword ptr [ebp-8]
00401038 mov dword ptr [ebp-4],eax
 
여기 서 우 리 는 간단 하기 위해 메모 리 를 풀 지 않 았 습 니 다. 그러면 어떻게 풀 어야 합 니까?delete p 인가요?호주, 틀 렸 습 니 다. delete [] p 일 것 입 니 다. 이것 은 컴 파일 러 에 게 제 가 삭제 한 것 은 하나의 배열 입 니 다. VC6 는 해당 하 는 Cookie 정보 에 따라 메모리 방출 작업 을 할 것 입 니 다.
자, 우 리 는 우리 의 주제 로 돌아 갑 니 다. 더미 와 스 택 은 도대체 어떤 차이 가 있 습 니까?
주요 한 차 이 는 다음 과 같은 몇 가지 가 있다.
1. 관리 방식 이 다르다.
2. 공간 크기 가 다르다.
3. 조각 이 다 를 수 있 습 니까?
4. 성장 방향 이 다르다.
5. 분배 방식 이 다르다.
6. 분배 효율 이 다르다.
관리 방식: 스 택 에 있어 컴 파일 러 가 자동 으로 관리 하 는 것 이 므 로 우리 가 손 으로 제어 할 필요 가 없습니다.더미 에 있어 서 방출 작업 은 프로그래머 가 제어 하면 memory leak 가 생기 기 쉽다.
 
공간 크기: 일반적으로 32 비트 시스템 에서 메모 리 를 쌓 으 면 4G 의 공간 에 도달 할 수 있 는데 이런 측면 에서 볼 때 메모 리 를 쌓 는 것 은 거의 제한 이 없다.그러나 스 택 에 있어 서 보통 일정한 공간 크기 가 있 습 니 다. 예 를 들 어 VC6 아래 에서 기본 적 인 스 택 공간 크기 는 1M (그런 것 같 습 니 다. 잘 기억 나 지 않 습 니 다) 입 니 다.물론 우 리 는 수정 할 수 있다.
프로젝트 를 열 고 다음 과 같은 메뉴 를 순서대로 실행 합 니 다: Project - > Setting - > Link, Category 에서 Output 을 선택 한 다음 Reserve 에서 스 택 의 최대 값 과 commt 를 설정 합 니 다.
메모: reserve 의 최소 값 은 4Byte 입 니 다.commt 는 가상 메모리 의 페이지 파일 에 저장 되 어 있 습 니 다. 스 택 을 크게 열 어 메모리 의 비용 과 시작 시간 을 증가 시 킬 수 있 습 니 다.
 
파편 문제: 더미 에 있어 빈번 한 new / delete 는 메모리 공간의 불 연속 을 초래 하여 대량의 파편 을 만들어 프로그램의 효율 을 떨 어 뜨 릴 수 있 습 니 다.스 택 에 있어 서 이 문 제 는 존재 하지 않 습 니 다. 스 택 은 선진 적 인 후에 나 온 대기 열 이기 때문에 그들 은 이렇게 일일이 대응 하기 때문에 스 택 중간에서 메모리 블록 이 튀 어 나 올 수 없습니다. 그 가 튀 어 나 오기 전에 그의 위 에 있 는 후진 스 택 내용 이 이미 튀 어 나 왔 습 니 다. 상세 한 것 은 데이터 구 조 를 참고 할 수 있 습 니 다. 여기 서 우 리 는 더 이상 일일이 토론 하지 않 겠 습 니 다.
성장 방향: 더미 에 있어 성장 방향 은 위로, 즉 메모리 주소 로 증가 하 는 방향 입 니 다.창고 에 대해 말하자면, 그것 의 성장 방향 은 아래로 향 하고, 메모리 주소 가 줄 어드 는 방향 으로 증가한다.
 
분배 방식: 더 미 는 모두 동적 으로 분배 되 고 정적 으로 분배 되 는 더 미 는 없다.스 택 은 두 가지 분배 방식 이 있 습 니 다. 정적 분배 와 동적 분배 입 니 다.정적 분 배 는 컴 파 일 러 가 완성 한 것 이다. 예 를 들 어 국부 변수의 분배 이다.동적 분 배 는 alloca 함수 에 의 해 분배 되 지만 스 택 의 동적 분배 와 더 미 는 다 릅 니 다. 그의 동적 분 배 는 컴 파일 러 에 의 해 방출 되 고 우리 가 손 으로 실현 할 필요 가 없습니다.
 
분배 효율: 스 택 은 기계 시스템 이 제공 하 는 데이터 구조 로 컴퓨터 는 바 텀 에서 스 택 에 지원 을 제공 합 니 다. 전문 적 인 레지스터 저장 스 택 의 주 소 를 분배 하고 스 택 에서 나 오 는 것 은 모두 전문 적 인 명령 이 집행 되 기 때문에 스 택 의 효율 이 비교적 높다 는 것 을 결정 합 니 다.더 미 는 C / C + + 함수 라 이브 러 리 에서 제공 합 니 다. 그 메커니즘 은 매우 복잡 합 니 다. 예 를 들 어 메모리 하 나 를 분배 하기 위해 라 이브 러 리 함 수 는 일정한 알고리즘 (구체 적 인 알고리즘 은 데이터 구조 / 운영 체제 참조) 에 따라 메모리 에서 사용 가능 한 충분 한 크기 의 공간 을 검색 합 니 다. 만약 에 충분 한 크기 의 공간 이 없다 면 (메모리 조각 이 너무 많 기 때 문 일 수 있 습 니 다).프로그램 데이터 세그먼트 의 메모리 공간 을 늘 리 기 위해 시스템 기능 을 호출 할 수 있 습 니 다. 그러면 충분 한 크기 의 메모리 로 나 누 어 되 돌 릴 수 있 습 니 다.분명히 쌓 는 효율 이 창고 보다 훨씬 낮다.
 
여기 서 우 리 는 창고 에 비해 new / delete 의 사용 으로 인해 대량의 메모리 조각 을 만 들 기 쉽다 는 것 을 알 수 있다.전문 적 인 시스템 지원 이 없 기 때문에 효율 이 매우 낮다.사용자 상태 와 핵심 상태 전환 을 일 으 킬 수 있 기 때문에 메모리 신청 은 대가 가 더욱 비 싸 졌 다.그래서 스 택 은 프로그램 에서 가장 광범 위 하 게 응용 되 고 함수 호출 도 스 택 을 이용 하여 완성 합 니 다. 함수 호출 과정 에서 의 매개 변 수 는 주 소 를 되 돌려 주 고 EBP 와 부분 변 수 는 모두 스 택 방식 으로 저장 합 니 다.그래서 우 리 는 쌓 는 것 이 아니 라 스 택 을 사용 하 는 것 을 추천 합 니 다.
 
스 택 은 이렇게 많은 장점 이 있 지만 쌓 는 것 에 비해 그렇게 유연 하지 않 기 때문에 가끔 은 대량의 메모리 공간 을 분배 하 는 것 이 좋 습 니 다.
쌓 이 든 스 택 이 든 크로스 오 버 현상의 발생 을 방지 해 야 합 니 다.그때 debug 는 상당히 어 려 웠 다.)
참, 또 한 가지 일이 있 습 니 다. 누 군가 스 택 을 합 쳐 말 하면 스 택 이라는 뜻 입 니 다. 쌓 는 것 이 아 닙 니 다. 하하, 알 겠 습 니까?
 
static 는 변수의 저장 방식 과 가시 성 을 제어 하 는 데 사용 된다
함수 내부 에서 정 의 된 변 수 는 프로그램 이 정의 처 에 실 행 될 때 컴 파일 러 가 스 택 에 공간 을 분배 합 니 다. 함수 가 스 택 에 분 배 된 공간 은 이 함수 가 실 행 될 때 방출 됩 니 다. 그러면 문제 가 발생 합 니 다. 함수 에서 이 변수의 값 을 다음 호출 에 저장 하려 면 어떻게 합 니까?가장 쉽게 생각 할 수 있 는 방법 은 전역 변 수 를 정의 하 는 것 입 니 다. 그러나 전역 변수 로 정의 하 는 것 은 많은 단점 이 있 습 니 다. 가장 뚜렷 한 단점 은 이 변수의 접근 범 위 를 파괴 하 는 것 입 니 다. (이 함수 에서 정 의 된 변 수 는 이 함수 에 의 해 만 제어 되 는 것 이 아 닙 니 다)
데이터 대상 이 특정한 대상 이 아 닌 전체 클래스 에 서 비 스 를 제공 하 는 동시에 이러한 패 키 징 성 을 파괴 하지 않도록 노력 해 야 한다. 즉, 이 구성원 에 게 클래스 의 내부 에 숨 기 고 외부 에 보이 지 않도록 요구한다.
 
static 의 내부 메커니즘:
정적 데이터 구성원 은 프로그램 이 시작 되 자마자 존재 해 야 합 니 다.함수 가 프로그램 실행 에서 호출 되 기 때문에 정적 데이터 구성원 은 그 어떠한 함수 에서 도 공간 을 분배 하고 초기 화 할 수 없습니다.
이렇게 하면 그의 공간 분 배 는 세 가지 가능 한 부분 이 있 는데 하 나 는 외부 인터페이스 로 서 의 헤더 파일 이 고 그곳 에는 이러한 성명 이 있다.두 번 째 는 클래스 정의 의 내부 실현 입 니 다. 거기에 클래스 의 구성원 함수 정의 가 있 습 니 다.셋째, 응용 프로그램의 main () 함수 전의 전역 데이터 성명 과 정의 처 입 니 다.
정적 데이터 구성원 은 실제 적 으로 공간 을 분배 해 야 하기 때문에 클래스 의 성명 에서 정의 할 수 없습니다 (데이터 구성원 만 설명 할 수 있 습 니 다).클래스 성명 은 하나의 클래스 의 '크기 와 규격' 만 설명 하고 실제 메모리 분 배 를 하지 않 기 때문에 클래스 성명 에 정 의 를 쓰 는 것 은 잘못된 것 입 니 다.헤더 파일 에서 클래스 성명 의 외부 정 의 를 내 릴 수 없습니다. 여러 개의 원본 파일 에서 중복 정 의 를 내 릴 수 있 기 때 문 입 니 다.
static 는 컴 파일 러 에 게 스 택 공간 이 아 닌 프로그램의 정적 저장 소 에 변 수 를 저장 하도록 도입 되 었 습 니 다. 정적 데이터 구성원 은 정 의 된 선후 순서에 따라 순서대로 초기 화 되 었 습 니 다. 정적 구성원 이 끼 워 넣 었 을 때 끼 워 넣 은 구성원 이 초기 화 되 었 는 지 확인 해 야 합 니 다.제거 할 때의 순 서 는 초기 화 된 반 순서 입 니 다.
 
static 의 장점:
메모 리 를 절약 할 수 있 습 니 다. 모든 대상 이 공유 하 는 것 이기 때문에 여러 대상 에 게 정적 데이터 구성원 은 한 곳 만 저장 하여 모든 대상 이 공유 할 수 있 습 니 다.정적 데이터 구성원 의 값 은 대상 마다 같 지만 값 은 업데이트 할 수 있 습 니 다.정적 데이터 구성원 의 값 을 한 번 업데이트 하면 모든 대상 이 업 데 이 트 된 값 을 액세스 할 수 있 도록 시간 효율 을 높 일 수 있 습 니 다.
정적 데이터 구성원 을 참조 할 때 다음 과 같은 형식 을 사용 합 니 다.
< 클래스 이름 >: < 정적 멤버 이름 >
정적 데이터 구성원 의 접근 권한 이 허용 된다 면 (즉, Public 의 구성원) 프로그램 에서 상기 형식 으로 정적 데이터 구성원 을 참조 할 수 있 습 니 다.

좋은 웹페이지 즐겨찾기