Chapter 16. 메모리 동적 할당.

Slides:



Advertisements
Similar presentations
Chapter 12. 배열. 배열  동일한 항목들이 동일한 크기로 연속적으로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는 자료 구조.
Advertisements

1 08 배열. 한국대학교 객체지향연구소 2 C 로 배우는 프로그래밍 기초 2 nd Edition 배열  동일한 자료유형의 여러 변수를 일괄 선언  연속적인 항목들이 동일한 크기로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는.
1. 2 차원 배열  배열은 동일한 데이터 유형으로 여러 개의 변수를 사용할 경우 같은 이 름으로 지정하여 간편하게 사용할 수 있도록 하는 것으로서 앞에서 1 차원 배열을 공부하였습니다.  2 차원 배열은 바둑판을 생각하면 되며, 1 차원 배열에서 사용하는 첨자를 2.
C 언어 (STS ) 10. Pointer Applications.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
ㅎㅎ 구조체 C++ 프로그래밍 기초 : 객체지향의 시작 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express Slide 1 (of 27)
Part 11 문자열 ©우균, 창병모 ©우균, 창병모.
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
제14장 동적 메모리.
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
-Part2- 제3장 포인터란 무엇인가.
C 8장. 포인터 #include <stdio.h> int main(void) { int num;
자료 구조: Chapter 3 (2)구조체, 포인터
7장 배열 ②.
개정판 누구나 즐기는 C언어 콘서트 제9장 포인터 출처: pixabay.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
5장 배열 작성자 : 변재현.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
Chapter 25. 메모리 관리와 메모리의 동적 할당
제 3장. C보다 나은 C++ II.
C 프로그래밍.
Dynamic Memory and Linked List
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
포인터 활용 포인터 활용.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express.
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
프로그래밍 랩 – 7주 리스트.
14장. 포인터와 함수에 대한 이해.
11장. 1차원 배열.
C 8장. 포인터 #include <stdio.h> int main(void) { int num;
C#.
JA A V W. 03.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
어서와 C언어는 처음이지 제14장.
13. 포인터와 배열! 함께 이해하기 IT응용시스템공학과 김 형 진 교수.
컴퓨터 개론 및 실습 11. 동적 메모리 할당.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
메모리 관리 & 동적 할당.
Java의 정석 제 5 장 배 열 Java 정석 남궁성 강의 의
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
19. 함수 포인터와 void 포인터.
3장. 변수와 연산자 교안 : 전자정보통신 홈페이지 / 커뮤니티/ 학술세미나
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
김선균 컴퓨터 프로그래밍 기초 - 7th : 함수 - 김선균
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
8주차: Strings, Arrays and Pointers
Chapter 08. 함수.
문자열 컴퓨터시뮬레이션학과 2015년 봄학기 담당교수 : 이형원 E304호,
^^ Computer Programming 2 dmpr.cnu.ac.kr/~daygax.
함수(Function) ◈ 함수의 개념 및 사용 이유 ◈ 함수 정의, 호출 및 선언 ◈ 지역변수와 전역변수 ◈ return 문
2nd day Indexing and Slicing
문자열 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
Homework #12 (1/2) 프로그램을 작성하고, 프로그램과 실행 결과를 프린트하여 제출한다.
컴퓨터 프로그래밍 기초 - 9th : 배열 / 포인터 -
구조체(struct)와 공용체(union)
Summary of Pointers and Arrays
실습과제 (변수와 자료형, ) 1. 다음 작업 (가), (나), (다)를 수행하는 프로그램 작성
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
제 29 강 스트링(string) 다루기 s a i s . s T i h t g r i n.
1. 지역변수와 전역변수 2. auto, register 3. static,extern 4. 도움말 사용법
어서와 C언어는 처음이지 제21장.
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
13. 포인터와 배열! 함께 이해하기.
Pointers summary.
6 객체.
2019 2학기 9장 배열과 포인터 1. 주소, 주소연산자(&) 2. 포인터, 역참조연산자(*) 3. 배열과 포인터.
Presentation transcript:

chapter 16. 메모리 동적 할당

프로그램을 작성하는 단계에서 필요한 기억공간의 크기를 결정하는 것은 정적할당이다. 동적할당의 필요성 프로그램을 작성하는 단계에서 필요한 기억공간의 크기를 결정하는 것은 정적할당이다. - 변수나 배열의 선언 프로그램의 실행 중에 입력되는 데이터에 맞게 기억공간을 확보해야할 때는 동적할당이 필요하다. - 세 명의 인사말을 저장하는 배열은 낭비가 심하다. char greetings[3][20]; // 가장 긴 인사말이 20바이트라고 할 때

메모리를 동적으로 할당하기 위해서는 함수를 호출해야 한다. ▶ 동적 할당 함수(malloc, free) 메모리를 동적으로 할당하기 위해서는 함수를 호출해야 한다. - int형 변수로 사용할 기억공간을 할당 받는 경우 - 포인터변수로 할당 받은 기억공간을 사용한다. *ip = 10; printf(“%d\n”, *ip); // ip가 가리키는 기억공간에 10을 저장한다. // ip가 가리키는 기억공간의 값을 출력한다.

▶ 메모리를 동적으로 할당 받는 프로그램 #include <stdio.h> #include <stdlib.h> int main() { int *ip; double *dp; ip=(int *)malloc(sizeof(int)); dp=(double *)malloc(sizeof(double)); *ip=10; *dp=3.4; printf("정수형으로 사용 : %d\n", *ip); printf("실수형으로 사용 : %lf\n", *dp); return 0; } // malloc함수를 사용하기 위해서 포함시킨다. // int형을 가리킬 포인터변수 // double형을 가리킬 포인터변수 // 기억공간을 동적으로 할당 받아서 // 각 포인터 변수에 연결시킨다. // 포인터변수로 각각 할당 받은 기억공간을 // 참조하여 값을 저장한다. // 포인터변수로 저장된 값을 출력한다. 정수형으로 사용 : 10 실수형으로 사용 : 3.400000 출력 결과

▶ 동적 할당되는 메모리는 반납해야 한다. 동적할당 메모리는 기업부류(storage class)의 힙(heap)영역에 할당된다. 힙(heap)영역은 프로그램이 종료될 때까지 기억공간이 유지된다. 따라서 사용이 끝난 동적할당 메모리는 명시적으로 반납한다. int *ip; ip=(int *)malloc(sizeof(int)); *ip=20; free(ip); // 포인터를 전달인자로 주고 호출한다.

▶ 동적 할당되는 메모리는 확인해야 한다. 동적할당함수는 힙 영역에 원하는 크기의 메모리가 존재하지 않으면 널 포인터를 리턴한다. 따라서 이 값을 확인하여 널포인터를 참조하지 않도록 해야 한다. ip=(int *)malloc(sizeof(int)); if(ip==0){ printf(“메모리가 부족합니다.\n”); } else{ *ip=10; printf(“%d\n”, *ip); // 리턴된 포인터가 널 포인터인지 확인한다. // 널 포인터이면 메시지만 출력한다. // 기억공간이 할당되었으면 사용한다. 널 포인터는 보통 “NULL”이라는 이름으로 기호화 하여 사용하는데 전처리 단계에서 0으로 바뀌므로 상수값 0과 같다.

메모리의 동적할당은 많은 기억공간을 한꺼번에 할당 받아서 배열로 사용하는 것이 효율적이다. 동적할당 기억공간의 활용 메모리의 동적할당은 많은 기억공간을 한꺼번에 할당 받아서 배열로 사용하는 것이 효율적이다. - int형 변수 5개를 동적으로 할당 받는 경우

▶ 메모리를 동적으로 할당 받아 배열로 사용하는 프로그램 #include <stdio.h> #include <stdlib.h> int main() { int *ip; int i, sum=0; ip=(int *)malloc(5*sizeof(int)); if(ip==0){ printf("메모리가 부족합니다!\n"); return 1; } printf("다섯 명의 나이를 입력하세요 : "); for(i=0; i<5; i++){ scanf("%d", ip+i); sum+=ip[i]; printf("다섯 명의 평균나이 : %.1lf\n", sum/5.0); free(ip); return 0; // 전체 20바이트의 기억공간 할당 // 메모리가 할당 되었는지 확인하여 // 메모리가 부족하면 메시지를 출력하고 // 프로그램을 종료한다. // 데이터를 저장할 포인터를 전달한다. // 입력된 값을 참조하여 누적한다. // 평균나이 출력 // 할당 받은 메모리 반환 출력 결과 다섯 명의 나이를 입력하세요 : 21 27 24 22 35 (엔터) 다섯 명의 평균나이 : 25.8

메모리 동적 할당을 사용하면 입력되는 문자열의 길이에 맞게 기억공간을 할당할 수 있다. ▶ 동적 할당을 사용하여 문자열을 처리하자. 메모리 동적 할당을 사용하면 입력되는 문자열의 길이에 맞게 기억공간을 할당할 수 있다. ① 문자열을 입력 받기 전에는 그 길이를 알 수 없으므로 우선 충분한 크기의 문자배열이 필요하다. ② 문자배열에 문자열을 입력 받는다. 뇌를 자극하는 C프로그래밍 ③ 문자열의 길이를 계산하여 그 크기에 맞게 기억공간을 동적으로 할당 받는다. ④ 동적으로 할당 받은 기억공간에 입력 받은 문자열을 복사한다. 뇌를 자극하는 C프로그래밍 입력된 문자열의 길이에 딱 맞는 기억공간

▶ 세 개의 문자열을 저장하기 위한 동적 할당 프로그램 #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char temp[80]; char *str[3]; int i; for(i=0; i<3; i++){ printf("문자열을 입력하세요 : "); gets(temp); str[i]=(char *)malloc(strlen(temp)+1); strcpy(str[i], temp); } printf("%s\n", str[i]); free(str[i]); return 0; // 문자열 처리함수를 위한 헤더파일 포함 // 동적 할당 함수를 위한 헤더파일 포함 // 임시 문자배열, 충분히 크게 확보한다. // 동적 할당된 기억공간을 연결할 포인터배열 // 반복 제어변수 // 문자열 입력 // 입력 받은 문자열의 길이에 맞게 동적 할당한다. // 동적 할당된 기억공간에 문자열을 복사한다. // 포인터배열의 요소를 참조하여 입력된 문자열 출력 // 할당 받은 메모리를 반환한다.

▶ 세 개의 문자열을 저장하기 위한 동적 할당 프로그램 문자열을 입력하세요 : Hi (엔터) 문자열을 입력하세요 : Let me introduce (엔터) 문자열을 입력하세요 : Hello (엔터) Hi Let me introduce Hello 출력 결과 - 포인터배열은 각 동적 할당 기억공간을 연결하여 가변배열을 만든다. 포인터배열은 널포인터로 초기화하여 문자열을 출력 할 때 널포인터를 검사하는 방법을 쓸 수 있다. char *str[100]={0}; for(i=0; str[i]!=0; i++){ printf(“%s\n”, str[i]); }

▶ 가변배열의 문자열을 함수로 출력하자. 가변배열에 저장된 문자열을 출력할 때 포인터배열의 배열명을 사용한다. str_prn(str); // 포인터배열의 배열명을 주고 함수 호출 포인터배열의 배열명은 (char *)형을 가리키므로 매개변수는 이중포인터변수를 사용한다. 매개변수를 사용하여 가변배열에 저장된 문자열을 출력한다. void str_prn(char **sp) { while(*sp!=0){ printf(“%s\n”, *sp); sp++; }

메인함수의 전달인자는 실행될 때 명령행에서 만들어진다. 운영체제는 명령행의 문자열을 가변배열로 만들고 그 개수와 포인터를 메인함수 에 전달한다.

▶ 명령행 전달인자를 출력하는 프로그램 #include <stdio.h> int main(int argc, char **argv) { int i; for(i=0; i<argc; i++){ printf("%s\n", argv[i]); } return 0; // 명령행 전달인자를 받을 매개변수 // 전달인자(문자열)의 개수만큼 반복 // 전달인자(문자열)를 하나씩 출력한다. 출력 결과 C:\>mycommand first_arg second_arg (엔터) MYCOMMAND first_arg second_arg C:\>_ 포인터배열의 마지막 배열요소는 널포인터로 채워지므로 널포인터를 검사하여 출력하는 것도 가능하다. while(*argv != 0){ printf(“%s\n”, *argv); argv++; } // argv가 가리키는 포인터배열의 값이 널포인터가 아닌 동안 // 문자열을 출력한다. // 포인터배열의 다음 배열요소로 이동

▶ 명령행 전달인자와 동적 할당을 사용한 문자열 입력 예제 다음과 같이 실행되는 프로그램을 만들어보자. 1. 입력되는 문자열을 길이에 맞게 동적으로 할당 받은 기억공간에 저장한다. 단, 문자열의 최대 길이는 널문자까지 포함하여 80바이트로 한다. 2. 프로그램을 작성할 때는 문자열이 몇 개가 입력될지 알 수 없으나 실행할 때는 명령행 전달인자로 그 최대값을 입력해 준다. C:\> strings 100 // 최대 100개의 문자열을 입력할 수 있다. 3. 새로운 문자열을 입력할 때 엔터키만 입력하면 입력을 끝내고 그 동안 입력된 문자열을 출력한다. C:\>strings 5 (엔터) 문자열을 입력하세요 : What's up! (엔터) 문자열을 입력하세요 : Good morning~ (엔터) 문자열을 입력하세요 : Hi... *^^* (엔터) 문자열을 입력하세요 : (엔터) What's up! Good morning~ Hi... *^^*

▶ 명령행 전달인자와 동적 할당을 사용한 문자열 입력 예제 4. 만약 최대 입력 문자열을 모두 입력하면 메시지와 함께 그 동안 입력된 문자 열을 출력하고 종료한다. C:\>strings 3 문자열을 입력하세요 : Cheer up. 문자열을 입력하세요 : Good evening. 문자열을 입력하세요 : Hello world! 문자열 입력이 최대값을 모두 채웠습니다. Cheer up. Good evening. Hello world! 5. 문자열을 입력하는 부분은 함수로 작성한다.

▶ 문자열을 입력하여 저장하는 프로그램 : PART1 #include <stdio.h> #include <string.h> #include <stdlib.h> void str_prn(char **); int main(int argc, char **argv) { char temp[80]; char **str; int max; int i; max=atoi(argv[1]); str=(char **)malloc((max+1) * sizeof(char *)); // strlen함수를 위한 헤더파일 // malloc, atoi함수를 위한 헤더파일 // 문자열 출력함수의 선언 // 명령행 전달인자를 매개변수에 받는다. // 문자열 입력을 위한 임시 문자배열 // 포인터배열을 연결할 이중포인터변수 // 최대 입력 문자열 수를 저장할 변수 // 반복 제어변수 // 문자열을 수치값으로 변환한다. // 포인터배열도 동적 할당한다. C:\>strings 5 실행하면 가변배열이 만들어진다.

▶ 문자열을 입력하여 저장하는 프로그램 : PART1 ▷ max=atoi(argv[1]); argv[1]이 연결하고 있는 숫자형태의 문자열을 수치값으로 바꾼다. atoi함수는 문자열을 전달인자로 받아서 수치값으로 바꾸어 준다. ▷ str=(char **)malloc((max+1) * sizeof(char *)); max의 수만큼 문자열을 연결할 포인터배열을 동적으로 할당 받는다. 이 때 데이터의 끝을 표시하기 위해 여분의 기억공간을 하나 더 할당 받는다. 할당 받은 기억공간은 이중포인터변수 str에 연결해 둔다.

▶ 문자열을 입력하여 저장하는 프로그램 : PART2 i=0; while(1){ printf("문자열을 입력하세요 : "); gets(temp); if(temp[0]=='\0') break; str[i]=(char *)malloc(strlen(temp)+1); strcpy(str[i], temp); i++; if(i==max){ printf("문자열 입력이 최대값을 모두 채웠습니다.\n"); break; } str[i]=0; str_prn(str); while(str[i]!=0){ free(str[i]); free(str); return 0; // 반복 제어변수 초기화 // 무한 반복 // 문자열 입력 // 엔터만 입력되면 temp배열의 첫번째 요소는 널문자가 된다. // 문자열을 저장할 메모리 할당하고 포인터 배열요소에 연결한다. // 문자열 복사 // 하나의 문자열을 입력할 때마다 하나씩 증가한다. // 입력된 문자열의 수를 검사하여 최대값을 다 채우면 바복문 종료 // 입력이 끝난 후에 포인터배열의 마지막 요소는 널포인터로 마감한다. // 입력된 문자열은 함수를 호출하여 출력한다. // 반복 제어변수를 초기화하고 // 포인터배열에 연결된 동적할당 기억공간들을 반환한다. // 동적으로 할당 받은 포인터배열의 기억공간도 반환한다.

▶ 문자열을 입력하여 저장하는 프로그램 : PART3 void str_prn(char **sp) { while(*sp != 0){ printf("%s\n", *sp); sp++; } // 매개변수는 이중포인터변수 // 포인터배열의 값이 널 포인터가 아닐 때까지 // 포인터배열이 연결하고 있는 문자열 출력 // 포인터배열의 배열요소를 차례로 이동한다.

calloc함수는 배열을 할당 받고 초기화한다. 기타 동적 할당 함수 calloc함수는 배열을 할당 받고 초기화한다. 첫 번째 배열요소의 개수, 두 번째는 배열요소의 크기를 전달인자로 준다. double형 변수 5개로 사용할 배열을 할당 받는 경우 double *ap; int i; ap=(double *)calloc(5, sizeof(double)); for(i=0; i<5; i++){ printf(“%lf\n”, ap[i]); } 출력 결과 0.000000 // 모두 0으로 // 초기화 된다.

▶ realloc 함수로 기억공간의 크기를 조절한다. 첫번째 전달인자는 이미 할당 받은 기억공간의 포인터를 준다. 두 번째는 새로 할당 받고자 하는 크기를 바이트 단위로 입력한다.

▶ realloc 함수를 사용한 양수값 입력 프로그램 #include <stdio.h> #include <stdlib.h> int main() { int *ip int size=5; int cnt=0; int num; int i; ip=(int *)calloc(size, sizeof(int)); while(1){ printf("양수를 입력하세요 => "); scanf("%d", &num); if(num<=0) break; if(cnt<size){ ip[cnt++]=num; } else{ size+=5; ip=(int *)realloc(ip, size*sizeof(int)); for(i=0; i<cnt; i++){ printf("%5d", ip[i]); } free(ip); return 0; // 입력된 데이터를 // 차례로 출력한다. // 처음에 5개만 입력한다. // 할당 받은 기억공간 반환 // 입력된 데이터의 수를 센다. // 일단 5개를 입력할 기억공간만 할당 받는다. // 입력된 데이터가 5개를 넘지 않으면 // 할당 받은 기억공간에 차례로 저장한다. // 그렇지 않으면 // 데이터의 최대값을 5씩 증가한다. // 새로 증가된 수만큼 기억공간을 늘린다. // 새로 할당된 기억공간에 저장한다.