12차시–동적할당 -...

25
12차시 – 동적 할당(3) 강C프로그래밍 26

Upload: others

Post on 14-Aug-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

12차시 – 동적 할당(3)

강C프로그래밍 26

Page 2: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

운영체제의 메모리 관리

운영체제의메모리 할당/해제

– 프로그램실행시 메모리제공

– 프로그램실행도중 메모리제공/해제

– 프로그램종료시 모든 메모리해제

운영체제의메모리 관리

– 메모리관리테이블운영

– 프로세스, 메모리크기, 시작위치관리

– 최적의방법에의해 메모리를할당

강C프로그래밍 27

Page 3: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

메모리 확보/반납

잦은 메모리 확보/반납은성능을 저하시킨다.

– 운영체제의메모리관리테이블을소진한다.

– 메모리관리를위해 해야하는많은 일이있다.

좋은 메모리 사용

직접 메모리 관리를 해야 할 수도 있다.

– 고급프로그래밍

– 실시간성능이중요시되는게임

강C프로그래밍 28

Page 4: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

메모리 관련 오류들

확보되지않은 공간에접근

반납한 메모리 접근

확보에 실패한 것을 모르는 경우

그 외

강C프로그래밍 29

Page 5: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

메모리 누수

메모리가새는 경우

– 사용가능한메모리가줄어든다.

– 사용중인메모리가계속늘어난다.

문제가 되는 경우

– 대형시스템

– 장기간동작하는서버

강C프로그래밍 30

Page 6: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

메모리 누수

char *block;

block = malloc(10);

strcpy(block, “Hello”);

block = malloc(100);

strcpy(block, “World”);

free(block);

강C프로그래밍 31

Hello

block(1)

(2)

Hello

block

World

(3)

Hello

block

World

(free)

(malloc)

(malloc)

?

Page 7: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

가비지 컬렉션

필요성

– 공간은있으나할당할수 없는상황

– 메모리관리자(운영체제)의역할이다.

– C에서는없다(Java는있다).

강C프로그래밍 32

10 바이트 10 바이트 10 바이트 10 바이트 10 바이트

10 바이트 10 바이트 10 바이트

(1)

(2)

(3) 10 바이트 10 바이트 10 바이트

20 바이트 ?

Page 8: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

배열과 결합된 형태

int *piarr[5];

int i;

for( i = 0 ; i < 5 ; i++)

piarr[i] = malloc (sizeof(int) * 5 );

강C프로그래밍 33

int *

int *

int *

. . .

int int int int

int int int

int int int int int

문제점은? 뒤에서 해결.

Page 9: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

문자열의 정렬

저장된 문자열을알파벳 순으로 정렬하라.

강C프로그래밍 34

h e l l o \0

n i c e \0

t o \0

m e e t \0

y o u \0

*strptr[5]

Page 10: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

문자열의 정렬

char *strptr[5];

char input[100], temp[100];

int i, j;

for (i = 0; i < 5; i++) {

gets(input); // 문자열을 입력 받은 후,

strptr[i] = malloc(strlen(input)+1); // 문자열 크기에 맞는 메모리 할당

strcpy(strptr[i], input); // 문자열 복사

}

// 버블 소트 시작

for (i = 0; i < 4; i++)

for (j = i; j < 5; j++)

if (strcmp(strptr[i], strptr[j]) > 0) { // 앞쪽 문자열이 더 크면

strcpy(temp, strptr[i]); // 앞 뒤 문자열 교환

strcpy(strptr[i], strptr[j]);

strcpy(strptr[j], temp);

}

강C프로그래밍 35

메모리 문제가있다.

Page 11: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

문자열의 정렬

if (strcmp(strptr[i], strptr[j]) > 0) {

strcpy(temp, strptr[i]);

strptr[i] = realloc(strptr[i], strlen(strptr[j])+1); // 메모리 조정

strcpy(strptr[i], strptr[j]);

strptr[j] = realloc(strptr[j], strlen(temp)+1); // 메모리 크기 조정

strcpy(strptr[j], temp);

}

강C프로그래밍 36

h e l l o \0

n i c e \0

t o \0

m e e t \0

y o u \0

*strptr[5]

(6바이트 할당)

(5바이트 할당)

(내용을바꾸려하면 strptr[1]에서메모리부족으로에러를낸다.

Page 12: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

문자열의 정렬

if (strcmp(strptr[i], strptr[j]) > 0) {

char *tempptr;

tempptr = strptr[i];

strptr[i] = strptr[j];

strptr[j] = tempptr;

}

강C프로그래밍 37

0

1

2

3

4

h e l l o \0

n i c e \0

t o \0

m e e t \0

y o u \0

0

1

2

3

4

h e l l o \0

n i c e \0

t o \0

m e e t \0

y o u \0

화살표의방향만바꾸어주면된다. 보기쉽게재정렬한형태.

Page 13: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

댕글링 포인터의 처리

강C프로그래밍 38

0

1

2

3

4

h e l l o \0

n i c e \0

t o \0

m e e t \0

y o u \0

두 개의공간은더 이상필요 없어해제했다.

0

1

2

3

4

h e l l o \0

n i c e \0

y o u \0

두 개의포인터는댕글링포인터가되었지만, 이를 알수 있는 방법은없다.

0

1

2

3

4

h e l l o \0

n i c e \0

y o u \0

NULL

NULL

댕글링포인터로두지 않고NULL로 설정한다. 이것은할당되지않음을의미하는약속이다.

Page 14: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

구조체와 결합된 자료형

struct { // 구조체의 배열로 선언한다.

int allocsize; // 할당한 공간의 크기를 넣는다. 처음에는 0을 넣는다.

char *ptr; // 할당할 메모리를 가리킨다.(전과 동일)

} strptr[5];

// 메모리를 할당할 때

strptr[2].ptr = malloc(3);

strptr[2].allocsize = 3;

strcpy(strptr[2].ptr, “to”);

// 해당 메모리에 다른 문자열(tempstr)을 넣을 때는?

강C프로그래밍 39

5

6

3

5

4

h e l l o \0

n i c e \0

t o \0

m e e t \0

y o u \0

allocsize ptr

Page 15: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

이중 포인터와 동적 할당

int **numptr[5]; // ①

numptr[0] = malloc(sizeof(int *) * 10); // ②

*numptr[0] = malloc(sizeof(int) * 5); // ③

**numptr[0] = 1; // ④

*(*numptr[0] +1) = 6;

printf("%d\n", **numptr[0]);

강C프로그래밍 40

0-99

100-199

200-299

300-399

400-499

0-9 10-19 20-29 30-39

1 6 3 9 4

14 18 12 10 19

24 22 29 26 21

37 39 36 32 34

① numptr

. . .

Page 16: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

배열의 단점

– 삽입, 삭제가어렵다.

강C프로그래밍 41

a b d e f … Z

0 1 2 3 4 100

c

a b d e … Y

0 1 2 3 4 100 101

Z

뒤로한 칸씩옮긴다.

a b c d e … Y

0 1 2 3 4 100 101

Z

공백이생겼으므로 c를넣는다.

뒤로 밀 때 주의해야한다.

Page 17: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

데이터가어디에 있든 위치만 연결하면된다.

강C프로그래밍 42

ab

de

z

Page 18: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

삽입

강C프로그래밍 43

a

b

de

z…

c

a

b

de

z…

c

Page 19: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

struct node {

int data;

struct node *next;

};

struct node *firstptr, *secondptr, *start;

firstptr = malloc ( sizeof(struct node) ); // ① 첫 번째 데이터

firstptr->data = 10;

start = firstptr; // 링크드리스트의 시작을 기억함

secondptr = malloc ( sizeof(struct node) ); // ② 두 번째 데이터

secondptr->data = 20;

firstptr->next = secondptr; // ③

secondptr->next = NULL; // ④

강C프로그래밍 44

Page 20: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

강C프로그래밍 45

20

1100

10

NULL

1100

1200

start

20

firstptr

10

NULL

secondptr1100

1200④

③start

struct node

struct node

Page 21: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

struct node *ptr, *start;

// 이미 노드가 생성되고 데이터가 들어있어야 한다.

ptr = start; // 링크드리스트의 시작점부터

for( i = 0 ; i < 5 ; i++)

ptr = ptr -> next; // 다섯번 건너뜀

printf(“여섯번째 노드의 데이터는 %d\n”, ptr->data );

강C프로그래밍 46

2010

start

3040

50

ptr

60

ptr = start

i=0i=1

i=2i=3

i=4

nextnext

nextnext

next

ptr->data = 60

Page 22: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

강C프로그래밍 47

2010

start

3040

5060

25

2010

start

3040

5060

25

ptr

newnode

Page 23: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

강C프로그래밍 48

struct node *ptr, *newnode;

ptr = start; // 링크드리스트의 시작점부터

insertvalue = 25; // 추가할 데이터

while (ptr) {

if (ptr->next->data > insertvalue) { // 삽입할 위치를 찾았다면

newnode = malloc( sizeof(struct node) );// 새 노드를 만들고

newnode -> data = insertvalue; // 값을 채우고

newnode -> next = ptr->next;// 추가된 노드의 다음 데이터 화살표 설정

ptr->next = newnode; // 앞 노드의 다음 데이터 화살표는 새 노드

break; // 노드 추가 완료

}

ptr = ptr -> next; // 다음 노드로 이동

}

Page 24: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

특징

– N번째데이터에도달하려면앞에서부터찾아야한다.

– 링크가끊어지면데이터가유실된다.

– 가장마지막노드의 next는 NULL이다. 데이터의끝을의미한다.

강C프로그래밍 49

Page 25: 12차시–동적할당 - elearning.kocw.netelearning.kocw.net/KOCW/document/2016/chungang/kimseungtae/12.pdf메모리관련오류들 확보되지않은공간에근 반납한메모리근

링크드리스트

단점과 그 해결

– N번째데이터를찾기위해 오래걸린다.

• 해결 : 배열의포인터로색인을 만든다.

– 운영에데이터보다링크가더 많다.

• 해결 : 데이터부분을 더 크게 한다.

강C프로그래밍 50

1번 데이터

11번데이터

21번데이터

31번데이터

포인터의 배열a

b

c

d

e

f

a

b

c

d

e

f

g

h

i

j

k

l

m

n

o

해결책을찾는 것은 여러분의몫