컴포넌트/라이브러리 자료실 소개한 Template TList 클래스인 TTList를 응용해서
간단한 문자열리스트 클래스인 TStringList와 비슷한 클래스를 만들어 보겠습니다.
(TTList는 세번째 수정된 ver1.1 것이 올라가 있는데 최신의 것을 사용해야 합니다)
class TSimpleStringList : public TTList<String>
{
typedef TTList<String> inherited;
public:
};
허... 실제 코드는 아무것도 없는 그냥 TTList<String> 형일 뿐이네요.
위 클래스는
typedef TTList<String> TSimpleStringList;
와 완전 동일합니다.
그러면 잘 동작하는지 테스트 해볼까요?
그런데 혹 메모리 누수가 있지 않을지 걱정이 될수 있습니다.
그거야 확인을 해보면 되죠.
힙메모리 누수 탐지의 간단한 기법은 해당 루틴을 실행하기 전에
메모리를 할당 받아 보고 그 번지를 기록하고
테스트할 해당 루틴을 실행하고 그 실행을 종료한뒤
다시 힙메모리를 할당 받아, 그 할당받은 번지를 비교해 보면 됩니다.
아래 처럼 말이죠.
//---------------------------------------------------------------------------
void add(String msg)
{
Form1->Memo1->Lines->Add(msg);
}
typedef TTList<String> TSimpleStringList;
void __fastcall TForm1::Button5Click(TObject *Sender)
{
// 메모리 누수 체크.
int *p = new int;
add(String().sprintf("before: %08X", p));
delete p;
{
// TEST
TSimpleStringList s;
s.Add(String("String class size:") + sizeof(String));
s.Add("안녕하세요");
s.Add("C++빌더입니다.");
s.Add(String("TSimpleStringList 입니다."));
s.Add("aaa");
s.Add("새거죠.");
s.Delete(4); // aaa 삭제.
s.Insert(4, "bbb"); // 그위치에 bbb 삽입.
s.Exchange(2, 3); // C++빌더입니다, TSimpleStringList입니다 바꾸기.
for(int c = 0; c < s.Count; c++)
{
add(s[c]);
}
}
p = new int;
add(String().sprintf("after: %08X", p)); // TSimpleStringList 메모리 누수 없음을 확인함.
delete p;
}
//---------------------------------------------------------------------------
화면에는 이렇게 찍힙니다.
Memo1
before: 00CA7EC8
String class size:4
안녕하세요
TSimpleStringList 입니다.
C++빌더입니다.
bbb
새거죠.
after: 00CA7EC8
간단한 스트링리스트 클래스인데 메모리 누수없이 잘 동작하죠.
TStringList를 아주 간단하게 구현한 것과 같습니다.
위의 예에서
s[1] = "새로운 문자열로 치환합니다.";
식으로 존재하는 문자열에 바로 대입도 가능합니다.
이는
String ss = "abc";
ss = "새로운 문자열로 치환합니다.";
처럼 사용하는 것과 같죠.
TTList가 템플릿 클래스이기 때문에 이와 같은 식으로 하면
여러 용도로 응용 가능합니다.
그런데 위에서 하나 의문점이 있죠.
메모장에 한줄씩 더하는 add(...) 함수를 사용했는데
어째서 여러줄의 데이타를 더했음에도 불구하고 메모리가 줄어들지 않을까?
이건 작은 문자열이할당 될때마다 계속 메모리해제 할당을 반복하면 효율이 떨어지기 때문에
작은 메모리에 대해서 빠르게 작업할수 있도록 미리 약간의 메모를 확보하고 있기 때문입니다.
|