[Step. 16] array 클래스에 non-CLI 오브젝트 사용

C++/CLI 2010. 10. 27. 09:00 Posted by 알 수 없는 사용자

C++/CLI은 네이티브 C++과 다르게 자료구조 배열을 사용하기 위해서는 array 컨테이너를 사용합니다.

array 컨테이너는 기본적으로 non-CLI 오브젝트는 사용할 수가 없습니다. 그러나 non-CLI 오브젝트가 포인터라면 사용할 수 있습니다.

 

아래는 array 컨테이너에 non-CLI 오브젝트를 사용한 경우입니다.

using namespace System;

 

class CNative

{

public:

           CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

           ~CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

};

 

int main(array<System::String ^> ^args)

{

           array<CNative>^ arr = gcnew array<CNative>(2);

           return 0;

}

 빌드하면 위에 이야기 했듯이 아래와 같은 빌드 에러가 발생합니다.


 

그럼 이번에는 non-CLI 오브젝트의 포인터를 사용해 보겠습니다.

#include "stdafx.h"

#include <iostream>

using namespace System;

 

class CNative

{

public:

           CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

           ~CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

};

 

int main(array<System::String ^> ^args)

{

           array<CNative*>^ arr = gcnew array<CNative*>(2);

           for(int i=0; i<arr->Length; i++)

           {

                     arr[i] = new CNative();

           }

 

           getchar();

           return 0;

}


이번에는 빌드에 문제가 없어서 아래와 같이 실행결과가 나옵니다.


 

그러나 위의 실행 결과를 보면 이상한 점을 발견하실 수 있을 것입니다. 그것은 CNative 오브젝트의 생성자는 호출하지만 파괴자는 호출되지 않은 것입니다. 이것은 array 컨테이너는 CLI 객체이므로 GC에서 관리하지만 non-CLI 오브젝트를 포인터 타입으로 사용한 것은 GC에서 관리하지 않으므로 만약 array GC에서 소멸 되기 전에 array에 담겨있는 non-CLI 오브젝트를 메모리(new로 할당한)를 해제하지 않으면 메모리 해제가 되지 않아서 메모리 릭이 발생합니다.

 

그래서 아래와 같이 array GC에서 소멸되기 전에 메모리를 해제하도록 해야합니다.

#include "stdafx.h"

#include <iostream>

using namespace System;

 

class CNative

{

public:

           CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

           ~CNative()

           {

                     Console::WriteLine(__FUNCTION__);

           }

};

 

int main(array<System::String ^> ^args)

{

           array<CNative*>^ arr = gcnew array<CNative*>(2);

           for(int i=0; i<arr->Length; i++)

           {

                     arr[i] = new CNative();

           }

 

           for(int i=0; i<arr->Length; i++)

           {

                     delete arr[i];

           }

          

           getchar();

           return 0;

}

 

실행 결과


이번에는 CNative의 파괴자가 제대로 호출되고 있습니다.



출처

도서 "C++/CLI In Action"

C++/CLI를 공부하시는 분들은 "C++/CLI In Action" 책을 꼭 한번 보시기를 추천합니다.