1 / 18

메모리 관리 및 저수준 자료구조 MANAGING MEMORY AND LOW-LEVEL DATA STRUCTURES

Chapter 10. 메모리 관리 및 저수준 자료구조 MANAGING MEMORY AND LOW-LEVEL DATA STRUCTURES. 10 장에서는 …. 지금까지는 표준 라이브러리에서 제공하는 vector 등의 컨테이너에 값을 저장했다 . 표준 라이브러리의 기능이 기본 언어가 제공하는 기능보다 더 융통성 있고 사용하기 쉽기 때문 … 10 장에서는 기본 언어가 제공하는 저수준 (lower-level) 테크닉 을 공부 컴퓨터 하드웨어 동작방식과 유사

meg
Download Presentation

메모리 관리 및 저수준 자료구조 MANAGING MEMORY AND LOW-LEVEL DATA STRUCTURES

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 10 메모리 관리 및 저수준 자료구조 MANAGING MEMORY AND LOW-LEVEL DATA STRUCTURES

  2. 10 장에서는… • 지금까지는 • 표준 라이브러리에서 제공하는 vector 등의 컨테이너에 값을 저장했다. • 표준 라이브러리의 기능이 기본 언어가 제공하는 기능보다 더 융통성 있고 사용하기 쉽기 때문… • 10장에서는 • 기본 언어가 제공하는 저수준(lower-level) 테크닉을 공부 • 컴퓨터 하드웨어 동작방식과 유사 • 사용하기 더 어렵고 때로 위험하기도 하지만, 잘만 쓰면 때에 따라 표준 라이브러리보다 더 효율적일 수 있다. • 배열과 포인터, 동적 메모리 할당, 파일에서 읽고 쓰기 등

  3. 포인터와 배열 • 배열 (array) • 일종의 컨테이너로서, vector와 비슷하지만 덜 강력 • 멤버 함수 없음 (.size() 등) • 포인터 (pointer)는 일종의 임의접근 반복자 • 배열의 요소를 접근하는데 사용 • 인덱싱으로도 요소에 접근 가능 • 포인터와 배열은 • C/C++ 의 가장 기본적인 자료구조에 해당 • 포인터 없는 배열은 더 이상의 존재가치가 없으며, 배열이 있어야 포인터의 유용가치도 더 커진다

  4. 포인터(pointer) • 포인터: 객체의 주소(address)를 값으로 갖는데이터 타입 • 모든 객체는 고유의 메모리 주소를 가지고 있다 • 포인터 변수 선언: int *p;// p는 정수 변수를 가리키는 포인터 • 주소 연산자(address operator)& • x가 객체일 때, &x는 x의 주소 • 역참조 연산자(dereference operator) * • p가 객체의 주소일 때, *p는 그 객체 자체 • p=&x하면 p는 x의 주소를 갖게된다. • p는 x를 가리키는(point to)포인터라고 부름. • 널 포인터(null pointer) • 포인터가 상수 0 (NULL)을 값으로 가짐. • 아무것도 가리키지 않는 상태. 포인터 초기화에 사용 p x 2000 1000 1000 5 int x = 5; int *p; p = &x; cout << *p; cout << x; cout << p; cout << &x;

  5. 포인터 • 포인터 선언 • p의 타입은 “int에 대한 포인터” • 실행 결과? (*p)와 q는 int 타입을 갖는다 int *p, q; = int* p, q; = int *p; int q; int main() { int x = 5; // p points to x int* p = &x; cout << "x = " << x << endl; // change the value of x through p *p = 6; cout << "x = " << x << endl; return 0; }

  6. 배열 • 배열은 일종의 컨테이너 • 표준 라이브러리가 아닌 기본 언어의 일부 • 배열 요소의 개수는 컴파일 시 알 수 있어야 함 • 동적으로 늘어나거나 줄어들 수 없음 • 배열의 크기를 나타내는 타입은 size_t • 예 • 배열의 이름은 배열의 처음 요소에 대한 포인터 • *coords=1.5; == coords[0]=1.5; const size_t NDim=3; double coords[Ndim]; double coords[3]; 숙련된 프로그래머

  7. 포인터 산술 연산 • 포인터는 임의 접근 반복자 • p가 배열의 m번째 요소를 가리킨다면, • p+n은 m+n번째 요소를 가리킨다 • p-n은 m-n번째 요소를 가리킨다 • 포인터가 반복자이기 때문에, • coords를 벡터에 복사하기 위해서는 • copy()를 이용해서 또는 • 벡터는 두개의 반복자를 사용해 생성할 수 있으므로, vector<double> v; copy(coords, coords+NDim, back_inserter(v)); vector<double> v(coords, coords+Ndim);

  8. 인덱싱(indexing) • 포인터는 배열에 대한 임의접근반복자이므로, • 인덱싱도 지원한다 • p가 배열의 m번째 요소를 가리킨다면, p[n]은 • m+n번째 요소이다. • 즉, *(p+n)과 같다 • a가 배열이라면, 배열이름은 처음요소의 주소이므로, a[n]은 • 배열의 n번째 요소이다. 즉, *(0+n)

  9. 배열 초기화 • 초기화 예 const int month_lengths[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; • 배열 선언시 초기화 값을 부여할 때, 배열의 크기를 명시적으로 나타내지 않아도 된다. • 컴파일러가 배열 크기를 자동으로 계산해줌

  10. 문자열 리터럴 다시 살펴보기 • 문자열 변수 const char hello[] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\0’}; • 리터럴 안의 문자들의 개수보다 하나 더 많은 요소를 포함. • 컴파일러는 문자열 끝에 ‘\0’를 붙여줌. 문자열이 끝나는 곳을 찾을 수 있도록 하기 위함 • 문자열 리터럴 • hello변수와 문자열 리터럴 “Hello”는 정확히 동일한 의미를 갖지만, • 변수와 문자열리터럴은 두 개의 구별되는 객체이므로, 서로 다른 주소를 갖는다. • 예) • 문자열의 길이를 알아내는 함수 size_t strlen(const char* p) { size_t size=0; while (*p++ != ‘\0’) ++size; return size; }

  11. 문자 포인터 배열 초기화하기 • 배열의 요소가 문자열인 예제 • 성적에 따라 학점 부여 (97이상 A+, 94이상 A, …) string letter_grade(double grade) { // range posts for numeric grades static const double numbers[] = { 97, 94, 90, 87, 84, 80, 77, 74, 70, 60, 0 }; // names for the letter grades static const char* const letters[] = { "A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D", "F" }; static const size_t ngrades = sizeof(numbers)/sizeof(*numbers); for (size_t i = 0; i < ngrades; ++i) { if (grade >= numbers[i]) return letters[i]; } return "?\?\?"; } 각 요소가 char* 타입 (문자열)인 배열

  12. main에 대한 인자들 • main함수도 함수이므로, 매개변수를 가질 수 있다. • 실행시킬 때,인자를 주어 동작 방식을 조종할 수 있다. • 실행 예: say.exe Hello, world • argc: 3 int main(int argc, char** argv) { // if there are command-line arguments, write them if (argc > 1) { // write the first argument cout << argv[1]; // write each remaining argument with a space before it for (int i = 2; i != argc; ++i) cout << " " << argv[i]; // `argv[i]' is a `char*' } cout << endl; return 0; }

  13. 파일 읽고 쓰기 • 표준 입력, 표준 출력 대신 파일에서 읽고 쓰기 • 많은 양의 입출력에 매우 유용 • 예, out.txt이라는 파일을 in.txt이라는 파일에 복사하는 프로그램 int main() { ifstream infile("in.txt"); ofstream outfile("out.txt"); string s; while (getline(infile, s)) outfile << s << endl; return 0; }

  14. 메모리 관리의 세 종류 if (…) { … string s; … … } 이때 생성되고, 블록이 끝날 때 해제 int* invalid_pointer() { int x; return &x; } 1) 지역 변수 • 정의부가 실행되는 시점에 생성되고, 정의부를 포함하는 블록의 끝에서 자동으로 해제. 자동 메모리 관리. • 이렇게 하면 문제 발생! 14

  15. 메모리 관리의 세 종류 // 이 함수는 OK int* pointer_to_static() { static int x; return &x; } 2) 정적 할당 (static allocation) • 처음 호출되기 전 어느 시점에 단 한번만 할당되고, 프로그램 실행 동안에 해제되지 않음 15

  16. 객체 할당 및 해제 p 42 43 3) 동적 할당 (dynamic allocation) T가 객체의 타입이라면, • new T는 타입 T의 객체를 할당하라는 명령 • 그 객체는 디폴트-초기화: 초기화 안되거나, 디폴트 생성자 실행 • 새롭게 할당된 (이름 없는) 객체에 대한 포인터를 돌려줌 • new T(args)하면 할당된 객체를args로 초기화 • 객체를 해제할 때는, delete p; • 예) int* p=new int(42); // *p는 42라는 값을 갖는 정수 객체 ++*p; // 객체의 값은 43이 된다. delete p; // 객체를 해제한다. 16

  17. 메모리의 영역 구분 동적 할당 힙(heap) 영역 new delete 스택(stack) 영역 지역변수 레지스터변수 정적(static) 영역 전역변수 정적변수 프로그램 코드

  18. 배열 할당 및 해제 char* duplicate_chars(const char* p) { // 널 추가해야하므로 +1 size_t length=strlen(p)+1; char* result=new char[length]; // 새로 할당된 공간에 복사, 첫째 요소에 대한 포인터 리턴 copy(p, p+length, result); return result; } • 배열 할당 예: new int[SIZE]; int* p=newint[1000]; // int p[1000];과 비슷 … delete[] p; // 배열을 해제한다. • 예) 문자열 복사 함수 18

More Related