[프로 그래 밍 언어] 더미 와 스 택 의 전면적 인 정리
7513 단어 프로 그래 밍
분 배 는 컴 파일 러 자신 이 주동 적 이 고 자신 이 주동 적 으로 방출 한다.스 택 에 대응 하 는 함수.매개 변수 저장 기능 값, 함수 호출 이 끝 난 후 완성 값 과 부분 변수의 함수 체 내.세그먼트 메모리 공간.그 조작 과 조직 방식 은 데이터 구조의 창고 와 매우 비슷 하 다.스 택 은 스 레 드 를 실행 하기 위해 남 겨 진 메모리 공간 입 니 다.함 수 를 호출 할 때 스 택 을 만 듭 니 다.함수 가 실행 되 었 을 때 스 택 은 회수 되 었 다.
운영 체제 의 더미:
프로그램 원숭이 가 수 동 으로 메모리 신청 과 방출 을 한다.프로그램 원숭이 가 수 동 으로 신청 하고 방출 한 메모리 블록 이 더미 에 저장 되 어 있 기 때문이다.쌓 인 메모리 블록 이 매우 많 기 때문에 쌓 인 조직 방식 은 링크 와 유사 하 다.운영 체제 의 더미 와 데이터 구조의 더 미 는 완전히 다르다.나 는 통속 적 인 이 해 는 이런 것 이 라 고 생각한다. 데이터 구조 중의 더 미 는 '구조 더 미' 이다.엄밀 한 논리 와 조작 방식 이 있다.운영 체제 의 더미.체인 시 계 를 사용 하여 '난잡 한 것들' 을 연결 하 는 것 같다.더 미 는 동적 분 배 를 위 한 메모리 공간 으로 그 생명 주 기 는 전체 응용 프로그램의 생명 주기 이다.
프로그램 이 끝 난 후에 더미 가 회수 되 기 시작 합 니 다.
모든 스 레 드 는 자신 만 의 스 택 이 있 지만 모든 프로그램 은 보통 하나의 더미 만 있 습 니 다.스 레 드 가 생 성 되 었 을 때.창고 의 크기 를 설정 하 였 습 니 다.
프로그램 이 시 작 될 때 쌓 인 크기 를 설정 합 니 다.창고 의 크기 는 일반적으로 고정 되 어 있 지만 쌓 기 는 필요 할 때 확장 할 수 있다. 예 를 들 어 프로그램 원숭이 가 운영 체제 에 많은 다른 메모 리 를 신청 할 때.
스 택 의 작업 방식 은 데이터 구조 중의 스 택 과 유사 하고 쌓 는 작업 방식 은 링크 와 유사 하기 때문에 스 택 은 쌓 는 것 보다 훨씬 빠 를 것 입 니 다.스 택 의 액세스 방식 에 따라 메모 리 를 풀 거나 새로 추가 하려 고 합 니 다.스 택 상단 지침 만 대응 하면 됩 니 다.더 미 는 먼저 메모리 의 여가 구역 에서 적당 한 메모리 공간 을 찾 은 다음 에 점용 해 야 한다.그리고 이 공간 을 가리 키 세 요.분명히 창고 보다 더 복잡 하 다.
다음은 스 택 과 더 미 를 나 누 어 진술 하려 고 했 으 나 같은 측면 에서 스 택 과 더 미 를 비교 하기 로 했다.비교 가 있어 야 뻔 하 다.
1. 스 택 을 만 들 때 스 택 의 크기 가 고정 되 어 있 습 니 다. 스 택 이 공간 을 계속 차지 해 야 하기 때 문 입 니 다.위의 글 에 속 한 더미 의 특성 에 따라 더미 의 크기 는 동태 적 이 고 그 분배 와 방출 도 동태 적 이다.
2. 스 택 에 있 는 데이터 가 너무 많 으 면 스 택 이 폭발 할 수 있 습 니 다.예 를 들 면 dfs 가 비 볐 다.
더미 도 터 지면...
。그럼 메모리 도 터 졌 다 는 거 야?
3. 모든 함수 의 스 택 은 각각 독립 되 어 있 지만 하나의 응용 프로그램의 더 미 는 모든 스 택 에 의 해 공유 된다.
공유 얘 기 가 나 온 이상 '병렬 액세스' 문제 가 생 겼 다.실제 병렬 접근 은 더미 에 의 해 제어 된다.스 택 에 의 해 제어 되 는 것 이 아니 라
4. 스 택 의 역할 영역 은 함수 내부 에 만 한정 되 고 스 택 은 함수 가 끝 날 때 스스로 공간 을 방출 합 니 다.그러나 쌓 여 있 는 변 수 는 수 동 으로 풀 어야 합 니 다.더미 속 의 변 수 는 역할 영역 에 문제 가 존재 하지 않 습 니 다.쌓 는 것 이 전체 국면 이기 때문이다.
5. 스 택 에 저 장 된 것 은 함수 반환 값 주소, 함수 매개 변수 입 니 다.함수 내의 국부 변수 등.더미 에 저 장 된 것 은 프로그램 원숭이 가 수 동 으로 신청 한 메모리 블록 (malloc, new 등) 이다.
6. 더미 와 창 고 는 모두 필요 에 따라 분배 한다.창고 에는 엄격 한 용량 상한 선 이 있다.쌓 인 용량 상한 선 은 '엄격 하지 않다'.쌓 기 는 고정된 용량 상한 선 이 없고 현재 의 남 은 메모리 양 과 관련 이 있다 (사실은 정확 하지 않 고 운영 체제 에 가상 메모리 나 다른 개념 이 있 기 때문에 쌓 는 작업 방식 이 추상 적 이다).
7. 스 택 상단 지침 을 이동 하면 스 택 메모리 의 분 배 를 실현 할 수 있 습 니 다.
더미 에 메모 리 를 분배 하 는 방법 은 현재 빈 메모리 에서 크기 를 만족 시 키 는 구역 을 찾 는 것 이다.링크 작업 방식 처럼.
8. 스 택 용량 을 초과 하지 않 아야 합 니 다.스 택 은 마음대로 메모 리 를 방출 하고 신청 할 수 있 습 니 다.메모리 에 고장 이 나 지 않 고 안전 합 니 다.더미 가 다 르 면 작은 메모리 블록 을 대량으로 신청 하고 방출 하 는 것 은 메모리 문 제 를 일 으 킬 수 있 으 며, 이 작은 메모리 블록 들 은 메모리 에 분산 되 어 있다.큰 메모리 신청 이 실 패 했 을 수도 있 습 니 다.비록 빈 메모리 가 충분 하지만.하지만 연속 은 아니다.이런 상황 에서 작은 메모 리 를 '조각 쌓 기' 라 고 한다.다만 큰 문 제 는 아니다."운영 체제" 에 관 한 지식 을 상세 하 게 보십시오.
9. 스 택 이 스 택 의 주 소 를 확정 한 후에 스 택 의 맨 위 에 있 는 지침 은 스 택 의 밑 에 있 는 주소 부터 시작 합 니 다.점차 낮은 주소 로 가다.즉, 스 택 의 저장 공간 은 높 은 주소 에서 낮은 주소 로 간다.
쌓 기 는 반대로 신청 공간 에 쌓 일 때 사용 가능 한 메모 리 를 점점 높 은 주소 로 찾는다.
순수한 문자 묘사 서술 이 무미건조 해 보인다. 우 리 는 코드 를 살 펴 보 자.
상기 코드 의 결 과 는 5, 3, 7 이다.
결과 에서 우 리 는 두 가지 일 을 볼 수 있다.
하 나 는 스 택 주 소 는 연속 적 인 것 입 니 다. 우 리 는 포인터 와 상대 적 인 크기 를 통 해 다른 변수 로 '오프셋' 할 수 있 습 니 다.
둘째, 그 중에서 창고 주 소 는 높 은 곳 에서 낮은 곳 으로 분포 되 어 있 고 창고 밑 은 높 은 곳 에 있다 는 것 을 알 수 있다.낮은 주소 로 성장 합 니 다.
그래서 프로그램 은 p + 1 이 아니 라 p - 1 입 니 다.
4. 567913. 다음은 함수 가 호출 될 때 발생 하 는 일 을 알 아 보 겠 습 니 다.
우선 운영 체제 가 이 함수 에 스 택 을 분배 했다.이 함 수 를 호출 한 후에 다음 문장 으로 정확하게 돌아 가 계속 실행 해 야 하기 때문에 첫 번 째 단 계 는 호출 된 함수 의 다음 명령 의 주 소 를 창고 에 넣 는 것 입 니 다.이렇게 하면 함수 호출 이 끝나 면 스 택 포인터 가 조금씩 메모 리 를 방출 한 후에.스 택 포인터 가 이 주 소 를 가리 키 면 정확 한 위치 로 돌아 가 계속 실 행 될 수 있 습 니 다.
4. 567913. 예 를 들 어 상기 코드 는 func 를 호출 하기 전에 먼저 func 의 다음 문장, 즉 printf 문장의 주소 입 니 다.창고 에 보관 하 다.
이렇게 함수 호출 이 끝 난 후에 이 printf 로 정확하게 돌아 가 계속 뒤로 실행 할 수 있 습 니 다.
여기 주 소 는 변수 주소 가 아니 라 명령 주소 입 니 다.그것 은 운영 체제 의 프로그램 카운터 (PC, 즉 Program Counter) 와 유사 하 다.
그 다음 에 실제 인삼 을 오른쪽 에서 왼쪽으로 순서대로 스 택 에 들 어 갑 니 다 (대부분의 C / C + 컴 파일 러 는 오른쪽 에서 왼쪽). 그 다음 에 함수 중의 각종 부분 변수 입 니 다.주의해 야 할 것 은 함수 중의 static 변 수 는 창고 에 들 어가 지 않 는 다 는 것 이다.
전역 변수 와 static 변 수 는 컴 파일 할 때 정적 저장 소 에 메모 리 를 할당 합 니 다.
이때 이 함수 가 또 다른 함 수 를 호출 했다 고 가정 하면 과정 도 마찬가지다.먼저 주 소 를 되 돌려 주 고 그 다음 에 매개 변수 와 부분 변 수 를 되 돌려 줍 니 다.
이렇게 하면 각 층 의 호출 이 끝나 고 스 택 의 포인터 가 계속 떨 어 질 때 이전 호출 된 위치 로 정확하게 돌아 가 계속 실행 할 수 있 습 니 다.창고 에서 나오다.메모리 방출 과정 이 라 든 가.창고 의 특성 에 따라 상 반 된 것 이 므 로 군말 하지 않 겠 습 니 다.
C 또는 C + + 프로그램 으로 보 이 는 메모리 주 소 는 다음 과 같은 다섯 개의 영역 으로 나 뉜 다.
창고 구역 (stack), 더미 구역 (heap), 전역 정적 구역 (static), 문자 상수 구역 과 프로그램 명령 구역.
창고 구역 과 더미 구역 앞 에 이미 소개 되 었 다.전역 정적 구역 은 전역 변수 와 정적 static 정적 변 수 를 저장 하 는 데 사 용 됩 니 다.전역 정적 은 두 개의 내용 으로 나 뉜 다. 하 나 는 초기 화 된 전역 변수 와 정적 변 수 를 사용 하고 하 나 는 초기 화 되 지 않 은 전역 변수 와 정적 변 수 를 사용 합 니 다.전역 정적 구역 은 더미 와 마찬가지 로 프로그램 이 끝 난 후에 운영 체제 에서 방출 됩 니 다.텍스트 상수 영역 은 상수 문자열 을 저장 하 는 데 사 용 됩 니 다.프로그램 이 끝 난 후 운영 체제 에서 방출 된다.
프로그램 명령 구역 은 프로그램 코드 를 저장 하 는 바 이 너 리 명령 을 이해 하 는 것 이 가장 좋다.
#include <iostream>
using namespace std;
void func()
{
int i = 5;
int j = 3;
int k = 7;
int *p = &i;
printf("%d
", *p);
printf("%d
", *(p-1));
printf("%d
", *(p-2));
}
int main()
{
func();
getchar();
return 0;
}
char *s = "hactrox"; // "hactrox" 는 문자 상수 구역 에 있 습 니 다.s 는 이 지역 의 "hactrox" 를 가리 키 기 때문에 이것 은 이해 할 수 있 습 니 다.먼저 텍스트 상수 구역 에 이 문자열 을 만 든 다음 s 는 이 문자열 과 같은 두 단 계 를 가리킨다.s 자 체 는 부분 변수 로 스 택 에 저 장 됩 니 다. /아래 코드 가 잘못 되 었 습 니 다. 지침 이 가리 키 기도 전에 바로 값 을 부 여 했 습 니까?int *p = 5; // 다음 코드 가 정확 합 니 다. 먼저 이 int 형 변 수 를 만 든 다음 p 가 이 변 수 를 가리 키 는 것 입 니 다.new 에서 온 int 변 수 는 쌓 여 있 습 니 다.int *p = new int(5); 다음은 흔히 볼 수 있 는 문 제 를 살 펴 보 겠 습 니 다. 다음 코드 에 문제 가 있 습 니까?문제 가 있 으 면 문제 가 어디 에 있 습 니까?
4. 567913. 문 제 는 두 번 째 함수 에 있 습 니 다. f2 는 그 문자열 을 정확하게 되 돌려 주지 못 합 니 다.함수 f1 에서."hactrox" 문자열 은 텍스트 상수 영역 에 생 성 됩 니 다.그리고 이 상수 문자열 의 주 소 를 되 돌려 줍 니 다. 문자 상수 구역 의 문자열 은 전역 적 이기 때문에 포인터 s 는 부분 변수 임 에 도 불구 하고 s 는 사라 지기 전에 대상 주 소 를 보 냈 습 니 다.그래서 s 소멸 여부 가 중요 하지 않 습 니 다.중요 한 것 은 되 돌아 오 는 주소 가 가리 키 는 영역 이 남아 있 기 때문에 정확하게 표시 할 수 있 습 니 다.함수 f2 에서."hactrox" 와 s 는 모두 국부 변수 입 니 다.그것들 은 창고 에 저장 되 어 있다.
s 가 같은 주 소 를 되 돌려 주 었 음 에 도 불구 하고.이 주소 가 가리 키 는 메모리 가 풀 렸 습 니 다.주 소 는 유효 하지만 목 표 는 유효 하지 않 습 니 다.그래서 출력 은 그냥 난 코드 입 니 다.문자 상수 구역 에 대해 서 는 다른 것 을 말 해 야 합 니 다.
void func()
{
int *p = NULL;
// 。 。
// 4 ( 4 ), 。
// , 。
int num = 100; // 。
int buffer[100]; // ,buffer 400
p = new int[100]; // , , 400 。
// p :p , 。
}
// 。 , p 。
// delete 。 。
char s[] = "hactrox";char *s = "hactrox again";
두 번 째 코드, 즉 문자 상수 구역 변 수 는 컴 파일 할 때 이미 확정 되 었 습 니 다.
첫 번 째 코드 는실행 할 때 할당 한 것 입 니 다.
이렇게 보면 2 단 코드 의 효율 이 높 은 것 같다.사실은 그렇지 않다.
실행 할 때 이 두 변 수 를 사용 할 때 첫 번 째 코드 에 대해 서 는.문자열 을 직접 읽 고 두 번 째 코드 에 대해 서 는 먼저 이 문자열 지침 을 읽 습 니 다.그리고 지침 에 따라 문자열 을 읽 으 면 효율 이 떨 어 지 는 것 이 분명 하 다.
사실 저 는 스 택 과 더 미 를 주목 하고 사실은 역할 영역, 생명 주기 와 유효성 에 관심 을 가 지 는 문제 라 고 생각 합 니 다.
지침 이 풀리다.포인터 가 가리 키 는 메모리 가 풀 리 는 것 은 아 닙 니 다.같다포인터 가 가리 키 는 메모리 가 풀 렸 습 니 다. 포인터 가 동기 화 되 거나 스스로 NULL 을 가리 키 는 것 은 아 닙 니 다. 포인터 가 실 효 된 주 소 를 가리 키 고 있 습 니 다.이 주 소 는 사용 할 수 없습니다.더 긴 유효 주 소 를 보장 할 수 있 는 사람 은 없다. 앞으로 무슨 일이 일어 날 지.
저작권 성명: 본 블 로그 의 오리지널 글, 블 로그, 동의 없 이 전재 할 수 없습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Linux Shell 프로 그래 밍 - 텍스트 처리 grep, sed사용자 가 지정 한 '모드' 에 따라 대상 텍스트 를 일치 하 게 검사 하고 일치 하 는 줄 을 인쇄 합 니 다. ##포함 되 지 않 음, 역방향 일치 \ ##키워드 앞 뒤 가 맞지 않 고 키워드 만 일치 합 니 다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.