strcpy_s 함수 사용으로 인해 발생한 버그를 잡느라 몇시간을 소비했다.

그 이유를 알아 보자.

우선 문제 발생한 코드를 간략하게 구현해 본다.


a[100] = "test1";

b[100] = "";

c[100] = "test2";

위처럼 선언을 하면

아래와 같이 메모리가 할당된다

a메모리 : 't', 'e', 's', 't', '1', '\0', '\0', '\0', , , , , , , , 

b메모리 : '\0', '\0', '\0', ,,,,,,,,

c메모리 :  't', 'e', 's', 't', '2', '\0', '\0', '\0', , , , , , , , 

이때 

strcpy_s ( b, 200, "test3" ); 

함수를 선언하면

어처구니 없게도 a메모리 공간에 있던(꼭 배열 a가 아닐수도 있다.) test1이라는 문자열은 사라지고 이상한(?) 

값들이 채워져 버린다.

(회사에서 vs2008, .c 로 코딩시 런타임 에러가 없었는데 집에서 vs2012, c++ 로 코딩시 런타임 에러가 뜬다.)

이유를 알아보자.


strcpy(char *dest, char *src);

이 함수는 dest 포인터가 가리키는 메모리 공간에 src 포인터가 가리키는 문자열을 복사한다.

문자열 복사후 남은 공간은 모두 '\0'(0, 널값) 으로 채운다.


strcpy_s(char *dest, size_t length, char *src);

이 함수는 dest 포인터 위치에 src 문자열을 length만큼 복사한다.  - 문제1

문자열 복사후 남은 공간은 모두 이상한(?) 값으로 채운다.  - 문제2

(msdn 페이지에서 strcpy_s함수 설명을 보면, 디버깅모드에서는 남은 공간을 0xfd값으로 채운다고 하나

내가 확인했을때는 -2라는 값이 들어가 있었다.)


이 버그는 문제1, 문제2의 특성때문에 일어난다.

 strcpy_s 함수는 문자열을 length만큼 복사하며(dest 메모리 공간보다 클지라도 복사해 버린다.) - 문제1

src문자열 복사 이후에는 모두 0xfd 문자로 채워 버린다. - 문제2


그렇기 때문에 a배열까지 침범하여 문자열 복사를 진행하였고 이때 a배열에는 '\0'값이 아닌 0xfd값이

채워지므로 a배열을 사용할때에는 이유도 모르게 값이 바뀌어 있는 것이다.



* 집에서 vs2012, cpp로 테스트 한 결과 런타임 에러를 즉각즉가 출력해줬음.

* 회사에서 재 확인




Posted by Yann'
,