strcpy_s등의 _s 류의 문자열처리 함수에 대해

 

VC++ 6.0으로 작성된 프로젝트를 VS 2005 이상으로 변환해서 컴파일 하거나,
VS2005
로 프로젝트 작성시 strcpy, sprintf, strcat 등의 C 런타임 함수를 사용하면 다음과 같은 warning 메시지를 접하게 된다
.

warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

strcpy_s, sprintf_s, strcat_s
와 같은 안전한 스트링 함수를 사용하라는 내용인데
...
이 함수들의 원형을 살펴보면 두번째 인자가 캐릭터의 숫자임을 알 수 있다
.
< 밑에 GrooveFella이 지적해주신대로 sizeof(buffer)가 아니라 _countof(buffer)로 계산해야 한다. >

errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );

strDestination 버퍼를 넘어서는 메모리 복사를 방지하는 스트링 함수라 이해하면 되겠다.
그래서 _s(afe)로 추측되는 함수들을 만들어 놨을 테고
...

그럼 이 보기 싫은 warnig을 어떻게 처리할 것인가
?
1.
제일 무식한 방법으로는 아래의 pragma를 설정하여, 해당 warnig을 표시하지 않도록 설정한다
.
  #pragma warning(disable: 4996)
2.
그게 아니면 당연히 _s류의 함수로 바꿔야 겠지?
여기서 한가지 집고 넘어가자면

char szBuf[MAX_PATH];
strcpy_s( szBuf, "aaa" );

형태의 코딩이 가능하다는 거다.

char *pszBuf = new char[MAX_PATH];
strcpy_s( pszBuf, "aaa");

이러한 코딩은 error C2660: 'strcpy_s' : 함수는2개의매개변수를사용하지않습니다.”라는 컴파일 에러가 발생한다.

두 코드의 차이점이 보이는가?
그렇다. _s류 함수의 첫번째 인자로 배열이 들어가면, 매크로에 의해 사이즈가 자동으로 계산된다.


3.
... 그럼 조금 더 생각해 보자.
strcpy_s
strncpy와 무엇이 다를까? 아니면 똑같이 동작하는가
?
아래의 코드를 돌려보면 답은 명확해 진다.

char *pszBuf = new char[6];
strncpy( pszBuf,
"aaaaaaaa", 7 ); // --> (1)
strcpy_s( pszBuf, 7,
"aaaaaaa"); // --> (2)

(1) 의 코드는 할당된 메모리(6byte)를 넘어서서 7byte까지 'a'로 채운 후 다음 코드가 진행된다.
(
머 이후의 상황이야 엄한 곳에서 메모리를 할당하거나 해제 할 때 문제가 발생 할 테지, 운이 억수로

나쁘다면 문제가 없는 것처럼 보일 수 도 있을 테고...)
(2)
의 코드는 메모리 에러를 발생시키며, 프로그램이 종료된다
.

귀찮다고 방치하지 말고, 이 기회에 바꿔보는 건 어떨까?

 

 

  1. GrooveFella 2010.08.27 16:49

    내용중에,
    "이 함수들의 원형을 살펴보면 두번재 인자가 버퍼의 사이즈임을 알 수 있다."

    약간 오해의 소지가 있을것 같아서 댓글남깁니다.
    정확히 말하자면, 버퍼 사이즈가 아니라, 캐릭터 수가 맞을것 같습니다.
    MSDN에서도 strcat_s( string, _countof(string), "strcat_s!" );
    이런식으로 _countof()를 사용하고 있습니다.
    혹시 sizeof를 사용하면 안되겠습니다.

    • 좋은향기 2010.09.03 18:26 신고

      그렇네요.sizeofbuffer가 아닌 numberOfElements 이군요.^^ 감사합니다.

  2. J.D 2014.04.30 21:39

    아 그래서 학교에서 내준 코드가 전부 병크 나는거였군요...

    scnf 등도 전부 _s 붙여줘야 되던데 같은 이윤가요?

    근데 결론적으로 저렇게 개의 매개 변수를 사용하지 않는다고 뜨면 어떻게 고쳐야 하는건가요? ㅜㅠ

  3. DanielPark 2015.08.27 22:47

    오~ 너무 좋은 내용이네요.
    그간 혼자 공부하면서,

    strcpy 관련 ~~
    안전한 ~~
    error c2660 ~~~

    위 3가지에 대한 궁금증을 한 방에 날려 주시네요.

    선배님 감사합니다.

+ Recent posts