Static duration means that the object or variable is allocated when the program starts and is deallocated when the program ends.
- MSDN
iTrans 버그 리포트 중에 아주 이상한 내용을 하나 들었다.
같은 자막을 두 번 변환하면 가 추가된다는 것…
제보해주신 분들과 연락을 해보니 static으로 선언한 어떤 부분의 데이터가 깨지는 게 원인이었다.
bool CSami2Srt::convISO88591(LPCTSTR lp, TCHAR &tc, int &len)
{
static LPCTSTR lpEntityNames[] = {
_T("quot"), _T("apos"), _T("amp"), _T("lt"), _T("gt"),
_T("nbsp"), _T("iexcl"), _T("cent"), _T("pound"), _T("curren"),
_T("yen"), _T("brvbar"), _T("sect"), _T("uml"), _T("copy"), ...
};
static TCHAR tcEntityValues[] = {
34, 39, 38, 60, 62,
32, 161, 162, 163, 164,
165, 166, 167, 168, 169, ...
};
static int lens[sizeof(lpEntityNames)/sizeof(lpEntityNames[0])];
static bool first=true;
if (first) {
first = false;
for (int i=0; i<sizeof(lpEntityNames)/sizeof(lpEntityNames[0]); i++) {
lens[i] = _tcslen(lpEntityNames[i]);
}
}
}
문제를 일으킨 부분이 바로 이 쪽이다.
lens[]라는 배열은 lpEntityNames[] 각 값의 길이를 저장하기 위해 만든 static 배열이다.
그리고, 당연히 이 배열은 프로그램이 실행되자마자 할당되고, 프로그램 종료시 해제된다.
더불어, static인 first로 인해, 최초 실행때 한번만 초기화되고, 종료시까지 유지된다.
그런데, 가끔 이 부분이 여러번 실행되면 저 lens[]의 내용이 망가지는 것이다.
그래서 위 코드의 15-22 행을 아래와 같이 바꿔봤다.
int lens[sizeof(lpEntityNames)/sizeof(lpEntityNames[0])];
for (int i=0; i<sizeof(lpEntityNames)/sizeof(lpEntityNames[0]); i++) {
lens[i] = _tcslen(lpEntityNames[i]);
}
별로 크게 바뀐 건 없고, 그냥 매번 이 메쏘드가 호출될 때마다 다시 길이를 계산하는 걸로 바꾼 것.
그런데, 이렇게 바꾸자 아무런 문제가 발생하지 않는다.
근데, 이렇게 하면 불필요한 _tcslen()이 너무 많이 실행이 될 것 같다.
그래서, 최종적으로 아래와 같이 바꿨다.
그냥, 각 항목의 길이를 별도로 저장하는 것으로…
static size_t nEntityLens[] = {
4, 4, 3, 2, 2,
4, 5, 4, 5, 6,
3, 6, 4, 3, 4,...
}
문제는 이렇게 해결을 했는데, 왜 처음의 방식에서 lens[]의 값이 바뀌었는지는 모르겠다.
내가 static의 개념을 잘 모르는 건가? OTL