2017-10-10 13 views
3

wcscpy_s 함수에 문제가 있습니다. wcscpy_s 뒤에 my 함수의 매개 변수 (stringOnestringTwo)를 읽을 수 없습니다. 다음은 간단한 데모로 문제를 보여줍니다.wcscpy_s 뒤에 문자열의 읽는 중 오류가 발생했습니다.

void testFunc(LPCWSTR stringOne, LPCWSTR stringTwo) { 

    wchar_t* defaultVal = L"Default"; 

    wchar_t tmp[100]; 

    int lenBefore = wcslen(stringOne); // Works 

    auto result = wcscpy_s(tmp, sizeof(tmp), defaultVal); 

    int len = wcslen(tmp); 

    int len2 = wcslen(stringOne); // Throws Exception Access violation 
} 


int main() { 
    testFunc(L"Test", L"Test"); 
} 
+1

하나의 문제점은 'sizeof (tmp)'는 크기를 * bytes *로 지정하지만 배열의 * 요소 * 수이어야한다는 것입니다. 예 : [이 'wcscpy_s' 참조] (https://msdn.microsoft.com/en-us/library/td1esda9.aspx). –

답변

2

wcscpy_s의 documentgation이 함수의 디버깅 버전은 특수 값 0xFE와 목적지 버퍼를 채우는 것을 말한다.

wcscpy_s(tmp, sizeof(tmp), defaultVal);을 호출하면 tmp 버퍼 크기를 전달하지만 wcscpy_s 길이는 문자 수로 나타납니다. 따라서 wcscpy_s에 전달하는 길이는 두 배가되고 버퍼는 0xfe으로 덮어 쓰기 때문에 원본 문자열 (L"Default";)의 길이가 작은 경우에도 버퍼 오버플로 및 정의되지 않은 동작이 발생합니다.

_sizeof(tmp) 대신 _countof(tmp)을 사용하십시오.

이것은 Visual Studio 디버거 사용 방법을 배우는 것이 좋습니다.

2

Michael Walz의 대답에서 이미 설명했듯이 잘못된 버퍼 크기를 전달하여 버퍼 오버플로가 발생했습니다.

대신 sizeof(tmp)_countof(tmp)를 사용하여 자신의 제안에 추가

, 내가 C++wcscpy_s() that automatically deduces the correct buffer size의 편리한 과부하가 있음을 추가하고 싶습니다 : 기본적으로

template <size_t size> 
errno_t wcscpy_s( 
    wchar_t (&strDestination)[size], 
    const wchar_t *strSource 
); // C++ only 

, 당신은 쓸 수 있습니다 간단하면 코드는 다음과 같이 작동합니다.

wchar_t tmp[100]; 

// Use the C++-only template overload of wcscpy_s 
// that automatically deduces the destination buffer size 
auto result = wcscpy_s(tmp, defaultVal); 

이 오버로드를 사용하면 sizeof/_countof 개의 버그가 일치하지 않습니다. 당신이 당신의 wchar_t tmp[100] 같은 정적 버퍼가있는 경우이 C++ 과부하가 C++ 컴파일러으로 만 작동

참고 컴파일 시간에 버퍼 크기를 알아낼 수 있어야합니다. 반면, 포인터에서 까지 동적으로 할당 버퍼가있는 경우 올바른 버퍼 크기를 명시 적으로 전달해야합니다.