사전지식:

1. dynamic allocation

- Allocating Memory with new - http://devgraphy.tistory.com/7?category=810547

- Freeing Memory with delete - http://devgraphy.tistory.com/8?category=810547

Class 코드는 Section 164(http://devgraphy.tistory.com/11?category=810224)와 다른게 없다. 다만, main에서 object를 동적 할당하기 때문에 object 선언하는 부분만 다르다.

int main()
{
    Car* c1 = new Car;    //dynamically create a class object
    cout << *c1;        //print out the object that c1 is pointing
    c1->speedUp();
    cout << *c1;
    c1->speedUp(25);
    cout << *c1;
    Car* c2 = new Car;
    Car* c3 = new Car;
    c1->speedDown(25);
    c2->speedUp(30);
    c3->speedUp(35);
    cout << *c1;
    cout << *c2;
    cout << *c3;
    delete c1;        //memory deallocation
    delete c2;
    delete c3;
}

작성한 class는 object를 생성할 때((line3,9,10)) class 영역에 컴파일되어 올라간다. 이 영역에 올라간 클래스는 설계도(흔한 예로, 붕어빵 틀)로 사용된다. c1은 object가 생성되면서 STACK영역에 올라간다(object의 주소를 STACK에 보관). 생성된 object를 "Instance"라고도 부른다.

c1은 object를 생성할 때 Car(double _v=0) 생성자를 호출한다. 또한 c1은 HEAP에 생성된 object를 reference(참조)한다.

Section 164에서의 object는 STACK 영역에서 빠르게 생성되고 자동으로 STACK에서 소멸된다( block( '}' )을 만남과 동시에!).

STACK에 생성된 c1,c2,c3 Pointer variable들은 HEAP에 생성된 object를 간접적으로 참조한다. 따라서 ->를 이용한다( '.' 과 구분!)

HEAP에는 STACK 영역보다 더 넓고, 필요한 만큼의 memory를 필요할 때 사용하므로 memory leak이 더 적다.

정리하면, object를 HEAP에 생성하는 것을 "object를 동적으로(dynamically) 생성한다"라고 말하며, 사용한 다음에는 반드시 delete를 사용해 제거해야한다. delete를 사용하면, ~Car() destructor를 호출하여 memory에서 object를 제거한다(Memory Deallocation). (Pointer variable c1, c2, c3를 제거하는 게 아니고 따라서 재활용 가능하다)

생성한 object를 delete하지 않으면 HEAP에 memory를 차지하게 된다. 이를 "Memory leak"이라 한다.

[그림: 객체 생성과 용어]

[그림: 객체 생성과 메모리]

 

앞서는 new를 이용해 heap memory에 공간을 할당하는 것(: 동적할당)을 배웠다면 이번엔 delete를 이용해서 할당한 공간을 해제하는 것을 배워보자.

 

먼저, 설명이 이루어지기 전에 사용하는 용어부터 통일하겠다.

free = deallocate = (new로 동적 할당한)메모리 해제

 

memory가 필요할 때 memory를 요청하기 위해 new를 사용하는 것은 단지 C++ memory management package의 절반일 뿐이다. 나머지 역할의 절반은 delete operator이다. 이것은 memory를 사용을 다 마쳤을 때 다시 memory pool에 memory를 return해주게 한다(다시 풀어준다고 생각).  이 작업은 memory의 가장 효율적인 사용하는 데 중요하다. return (또는 free) 한 memory는 다음에 프로그램의 다른 부분에 의해 재사용될 수 있다. delete의 원리는 원래의 new로 할당된 memory block을 가리키는 pointer를 가지고 memory를 해제하는 것이다.

 

int* ps = new int;        //allocate memory with new

delete ps;               //free memory with delete when done

 

위의 delete는 ps가 가리키는 memory를 지운다; Pointer ps자체를 지우는 것은 아님을 기억하자. 예를들어, 우리는 ps를 다른 new allocation을 가리켜서 재사용할 수 도 있다.

 

Note. 항상 new와 delete의 사용의 균형을 맞춰야 한다; 그렇지 않으면 결국엔 memory leak(memory가 할당되어서 더이상 재사용될 수 없음)이 일어난다. 만약 memory leak이 굉장히 커지면 더 많은 memory를 찾느라 프로그램이 중단되는 것을 초래한다.

 

Note. 이전에 free된 memory block을 중복하여 free하려고 시도해서는 안된다. C++ 표준은 "그러한 시도의 결과는 undefined이고, 어떠한 결과든 일어날 수 있음을 의미한다.

 

Note. 또한 ordinary variable로 선언한 memory를 free하기위해 delete를 사용해서는 안된다.

 

 

 

 

Caution. 반드시 new로 할당된 memory를 free하는 데에만 delete를 사용해야 한다. 그러나, null pointer에 delete를 사용하는 것은 안전하다.

 

결과부터 말하면 불리한 결과를 초래한다. 만약 object가 new를 사용하지 않고 ordinary variable(stack에 저장)로 정의되었다면, 컴파일러는 scope의 끝에서 destructor에게 호출한다 (함수가 끝나면 그 안의 local variable들은 모두 소멸하는 원리). 이 말은 즉 destructor를 두 번 호출하고 안 좋은 영향을 가져올 수 있음을 의미한다.

 

first destructor -> 우리가 써준 delete object

second destructor -> implicitly delete at the end of the scope

 

destructor를 두번 호출하는 것과 더불어, 절대 할당하지 않은 memory block을 deallocate하려고 시도하는 것이다. new는 object를 heap에 올려 놓는데, delete는 new 가 올려놓은 같은 곳에서 object를 찾게 된다. 그러나 new로 할당되지 않은 object는 stack에 존재하고 있다.

이것은 프로램의 crash를 유발한다.

 

 

 

---------------------------------------------------------------------

Management Records

Using new to Create Dynamic Arrays(add)

---------------------------------------------------------------------

+ Recent posts