반응형

Static duration means that the object or variable is allocated when the program starts and is deallocated when the program ends.

- MSDN


iTrans 버그 리포트 중에 아주 이상한 내용을 하나 들었다.

같은 자막을 두 번 변환하면  가 추가된다는 것…


제보해주신 분들과 연락을 해보니[각주:1] 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


  1. 아무리 해봐도 내 PC에선 재연이 안 됐음 [본문으로]
반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band