2013-04-22 16 views
2

] C++에서 매우 새로운 기능이므로 비교적 간단한 문제이지만 C++ 응용 프로그램이있어 힙 손상 문제를 추적하려고합니다. 이 기능으로 추적 한 :삭제시 힙 손상 오류 [

void LTrimZeros(CString *pstr) 
{ 
    char *psz1; 
    char *psz2; 

    if (pstr->GetLength() == 0) 
     return; 


    psz1 = new char[pstr->GetLength() + 1]; 
    psz2 = psz1; 

    strcpy_s(psz2, strlen(psz2), (const char *) *pstr); 

    while (*psz2 == '0') 
    { 
     psz2++; 
    } 

    *pstr = psz2; 

    delete [] psz1; 

    return; 
} 

psz1는 힙 손상 오류가 발생을 삭제하려고합니다. 다시 C++에 익숙하지 않기 때문에이 문제를 해결하고 우연히 메모리 누수가 발생하기를 원치 않으므로 전문가에게 물어볼 것이라고 생각했습니다. 이 응용 프로그램은 원래 C++ 4와 같은 방식으로 작성되었지만 이제는 C++ 11로 업그레이드 되었기 때문에 동일한 기능의 대체 솔루션도 훌륭합니다 (왜 이것이 힙 손상으로 인해 많은 도움이되는지 설명하는 간단한 설명).

+0

그런 다음 생산 코드가 맞습니까? – trojanfoe

+3

'std :: string' 마침표를 사용하십시오! 모든 포인터가 엉망으로되는 것을 제거하십시오. –

+0

whilte 루프에서는 * psz2 == '0'입니까? 또는 * psz2 == '\ 0' – Ali

답변

3

strlen(psz2)은 초기화되지 않은 메모리를 읽으므로 어레이의 끝을 넘어 읽을 수 있습니다. 즉, strcpy_s에 전달하는 길이는 예측할 수 없으며 psz1에 할당 된 메모리 끝을 초과하여 글을 쓸 수 있습니다.

함수의 끝을 가정하면 당신은 Win32에서 여기 문제가 실행할 수 있습니다, 당신은 단순히

strcpy_s(psz2, pstr->GetLength() + 1, (const char *) *pstr); 

strcpy_s 라인을 변경할 수 있습니다 (I 충분히 확실히 말할 CString에 익숙하지 않다) 유효 UNICODE_UNICODE에 따라 8 비트와 16 비트 문자 사이를 전환하는 문자열 처리 함수를 정의합니다. 나는 Alok Save와 다른 사람들이 std::string을 사용하는 것으로 전환하는 것이 더 명확하고 간단하다는 것에 동의한다. MSDN에서

+0

'* pstr = psz2;는 어떨까요? 'CString'이 그것을 지원합니까? 아니야. – trojanfoe

+0

@trojanfoe, Captain Oblivious 나는 그 기능을 훨씬 능가하지 못했습니다. 나는 그에 맞게 내 대답을 바꿀 것이다. – simonc

+0

'psz2 = psz1;'그것은''psz2''가 단지''새롭게 실행 된''psz1''을 가리키고있는 것을 의미하지 않습니까? –

2

: 여기

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

, 당신의 코드에서, 당신은 초기화되지 않은 배열에 strlen을 요구하고있다, 당신은 (대상 버퍼가를 저장할 수있는 요소의 최대 수를 전달)을 수정해야합니다 :

+1

strcpy_s()에 길이 매개 변수로 strlen (psz2)를 전달하는 버그를 복사하지 않았습니까? – harper

+1

예, 여기에 버그가있는 정확한 줄을 표시하고 버그 수정을 표시하지 않습니다 (독자에게 연습 문제로 남겨 두었습니다 - 정말 쉽습니다). – piokuc