본문 바로가기
IT/C++

_tcscpy_s 사용시 주의사항

by Spring Up!! 2016. 9. 10.
반응형

https://msdn.microsoft.com/ko-kr/library/td1esda9.aspx 의 내용을 기반으로 작성합니다

TCHAR.H 루틴

_UNICODE 및 _MBCS 미정의

_MBCS 정의됨

_UNICODE 정의됨

_tcscpy_s

strcpy_s

_mbscpy_s

wcscpy_s


함수 인자는 다음과 같다

errno_t wcscpy_s(
   wchar_t *strDestination,
   size_t numberOfElements,
   const wchar_t *strSource 
);

strDestination

대상 문자열 버퍼의 위치입니다.

numberOfElements

대상 문자열 버퍼의 크기로, 내로(narrow) 함수와 멀티바이트 함수의 경우 char 단위이고 와이드(wide) 함수의 경우wchar_t 단위입니다.

strSource

null 종료 소스 문자열 버퍼입니다.


얼마전 이 함수를 쓰다 헤메었던 적이 있었다

TCHAR Buffer[128];

_tcscpy(Buffer, sizeof(Buffer), _T("Good Morning!"));

이렇게 작성했는데 자꾸 바로 전에 선언된 변수의 메모리 영역을 침범하는 에러가 발생되었다

이유는 2번째 인자에 있었다

numberOfElements 는 버퍼의 크기이지만 내로(narrow) 함수와 멀티바이트 함수의 경우 char 단위이고 와이드(wide) 함수의 경우wchar_t 단위 이라고 되어 있다

따라서 아래와 같이 바꿔야 한다

TCHAR Buffer[128];

_tcscpy(Buffer, _countof(Buffer), _T("Good Morning!"));


위 예제의 경우

sizeof(Buffer) 는 256 이고, _countof(Buffer) 는 128 을 반환하기 때문에 Buffer 의 크기를 넘어가게 된다

그렇다면 위의 예제의 경우에는 Good Morning! 는 13자이기 때문에 버퍼크기(128) 을 넘어가지 않는데? 라고 생각할 수 있을 것이다

MSDN 에 아래와 같은 내용이 있다

이러한 함수의 디버그 버전은 우선 0xFE로 버퍼를 채웁니다. 사용 하 여이 동작을 사용 하지 않으려면_CrtSetDebugFillThreshold합니다.

즉 디버그 버전에서는 Good Morning! 을 복사하고 남은 영역을 0xFE 로 채우기 때문에 위 예제의 경우 버퍼의 영역을 넘어서 wchar_t 128개의 공간을 0xFE 로 채우게 된다. 그래서 다른 메모리 영역을 침범하게 되는 것이다.


0xFE0xFE 로 채워진 버퍼

메모리가 0xFE 로 채워져 있는 것을 볼 수 있다

프로그램은 결국 다음과 같은 메시지를 출력하게 된다

Stack around the variable was corrupted

그렇다면 Release 버전에서는 괜찮았을까?

그렇다. 나머지 공간에 0xFE 를 채우지 않기 때문에 위의 예제의 경우 문제를 일으키지는 않는다.

왜 0xFE 로 채우는지 궁금했는데, 이런 종류의 에러를 막기 위해서였던 것 같다

반응형

댓글