카테고리

asm (27) bootloader_x86_grub (1) C (92) compile (11) config (76) CPP (13) CSS (1) debugging (7) gimp (1) Go (1) html (1) Java (1) JavaScript (1) kernel (19) LibreOffice (3) Linux system progamming (21) MFC (1) opencv (4) OpenGL (1) PHP (1) Python (4) qemu (29) shell (3) socket (7) troubleshooting (2) ubuntu18.04 (2) windows (1)

2018/12/16

C 언어 메모리 할당 영역 정리


1. 메모리 할당
메모리 할당
정적 메모리 할당(배열)
동적 메모리 할당

할당 된 메모리 다른 영역
code: 코드 영역
초기화 된 데이터: data 영역
초기화 되지 않은 데이터: bss 영역
Heap
스택 Stack
Segment(영역)
설명
stack 크기가 초기화에 정해지지 않는다
실행 할 때 메모리 크기가 설정된다
(메모리 크기 변화)
(메모리 크기 변화)
heep 크기가 초기화에 정해지지 않는다
실행 할 때 메모리 크기가 설정된다
BSS 영역(초기화 되지 않은 데이터) 초기화 하지 않는 변수가 위치하는 영역,
0으로 초기화된 변수의 내용도 포함한다
main(){static int a;}
컴파일 하는 순간 크기가 정해 된다.
Data 영역( 초기화 된 데이터) 초기화된 변수가 위치 하는 영역.
컴파일 하는 순간 크기가 정해진다.
CODE 영역(text) 코드가 바이너리 형식으로 위치하게 된다.
컴파일 하는 순간 크기가 정해진다.



code 영역
  • 텍스트 영역이라 하며 읽기 전용
  • 실행 가능 명령어가 있는 오브젝트 파일을 포함.
  • read-only == object file : 읽어와 실행만 한다.
  • 코드만 위치하며 컴퓨터(CPU 연산)가 읽어 실행만 하는 영역
  • 변경 하려면 재 컴파일해 오브젝트 코드를 다시 만들어야 한다.



data 영역
  • 실행시간에 변경할 수 있는 초기화 된 변수를 포함 한다.
  • 고정되어있는 Global, static, constant external 변수 초기화.
  • 컴파일 후 크기기 지정된다.
  • 이 영역의 크기는 실행 시간에 변경되지 않음.
  • 단지 초기화된 변수가 들어간다

bss 영역
  • 초기화되지 않은 Global, Static external 변수 저장 (0으로 초기화 됨)
  • 컴파일 후 크기가 지정되며, 초기화 하는 변수의 총 수량으로 크기가 설정된다.
  • 영역의 크기는 실행 시간에 변경 되지 않음.
  • 이 영역은 오브젝트 파일에서 실제 공간을 차지 하지 않는다.(Bss 영역의 길이만 저장 됨).

Object 영역
  • data 영역은 모든 자료에 대한 값을 가진다.
  • bss 영역은 초기화 하지 않는 변수의 총 수량만 가진다.

1.1 스택 메모리
다음 정보는 스택에 저장 된다.
  • 지역 변수 : 함수 안에서 사용되는 변수
  • 함수 인수의 값: 스택으로 전달되는 값
  • 리턴 주소(PC의 값): 복귀 주소 값(함수 복귀 조소 값 저장 후, 호출된 부분으로 이동 처리 후 복귀)

예제
#include <stdio.h>

int add2(int a, int b);

void main(void){
int i=5, j=7, n;

n=add2(i,j);
printf("SUM is %d\n", n);
}

int add2(int a, int b){
return (a+b)
}

2. 힙 메모리
힙 메모리의 할당된 구조
  • 함수에서 생성 하지만, 함수를 지속적으로 사용 할 때 우회해 사용된다.
  • 프로그램 코드 작성할 때 동적 메모리 할당을 해야 하는 경우에,
  • 동적 메모리 할당을 하게 코드를 작성한다.
  • 메모리가 설정되면 Heap memory 영역에 할당된다.
  • 동적 메모리의 할당과 해제 때문에 heap memory 영역의 크기가 가변적으로 변경이 된다.
  • 동적 메모리 할당을 했으면 메모리 자원 반납을 위해 꼭 해제한다.

문제점
할당 및 사용 가능한 메모리 공간 관리
할당 해제 및 가비지 수집

2.1 힙 메모리 할당
void *malloc(size_t size);
malloc(size_t size);
자료형
주소 값 0x1200
단위
void *원하는 자료형캐스팅 필요
블록
블록
Byte
  • 바이트 크기 블록 할당
  • 블록에 대 한 포인터 반환 (할당이 실패 하는 경우 NULL)

void *calloc(size_t num_elements, size_t element_size));
calloc(size_t num_elements, size_t element_size));
자료형
주소 값 0x1300
단위
void *원하는 자료형캐스팅 필요
블록 0 초기화
블록 0 초기화
Byte
  • num_elements * element_size 바이트 블록 할당
  • 모든 바이트를 0으로 초기화.
  • 블록에 대한 포인터 반환 (할당이 실패 하는 경우 NULL)

void *realloc(void *ptr, size_t new_size)
  • 블록 크기를 new_size로 변경
  • 새로운(크기 조정 된) 블록의 포인터를 반환.
  • 이전 블록의 내용은 새 할당 된 블록에 복사 될 수 있다.
  • malloc/calloc/realloc의 반환 값을 캐스팅해야 할 수도 있다.
  • int * pi = (int *) malloc (BUFFER_SIZE);
2.2 힙 메모리 할당 해제
void free(void *pointer);
이전에 할당 된 메모리에 대한 포인터 필요.
메모리 공간을 heep으로 다시 확보

기억
 할당 된 메모리가 더 이상 사용되지 않으면 해제한다.
"메모리 누수" 문제가 발생할 수 있다.
디버깅 하기 어렵다!

malloc free 예제
#include <stdio.h>
#include <stdlib.h>

void main(void){
int i, *p, n=10, m=20;

/* allocate n interger blocks */
if (( p = (int *) malloc(n * sizeof(int))) == NULL){
perror("Malloc memory allocation failed.");
exit(0);
}
for (i=0; i<n; i++){
p[i] = i;
}

/* m 블록을 p 블록의 끝에 추가한다. */
if (( p = (int *) realloc(p, (n+m) * sizeof(int))) == NULL){
perror("realloc memory allocation failed.");
exit(0);
}
for (i=n; i < n+m; i++){
p[i] = i;
}

/* 새로운 배열 출력 */
for(i=0; i<n+m; i++){
printf("%d\n", p[i];)
}

free(p); /* return p to available memory pool */
}

동적 할당을 사용하는 배열
#include <stdio.h>
#include <stdlib.h>

void main(void){
int *pS, j;
int i32Num = 20;

if((pS = (int *) malloc(i32Num * sizeof(int))) == NULL){
perror("malloc memory allocation failed.");
exit(0);
}
for(j=0; j<i32Num; j++){
pS[j] = j;
}

/* print new array */
for(j=0; j<i32Num; j++){
printf("%d\n", pS[j]);
}
free(pS);
}

#include <stdio.h>
void main(void){
int pS[20], j;
int i32Num = 20;

for(j=0; j<i32Num; j++){
pS[j] = j;
}

for(j=0; j<i32Num; j++){
printf("%d\n", pS[j]);
}
}

댓글 없음:

댓글 쓰기