2012-01-12 3 views
0

프로그램이 있는데, '다운로드'버튼을 클릭하면 웹 페이지를 다운로드하고 동적 할당 char* 변수에 저장하는 새 스레드를 만듭니다.(Visual C++) 포인터를 삭제 한 후에 동적 할당 메모리가 유효하지 않습니다.

하지만 지금은 '다운로드'를 클릭, 프로그램은 다음 정보를 보여줍니다

--------------------------- 
Microsoft Visual C++ Debug Library 
--------------------------- 
Debug Assertion Failed! 

Program: d:\dev\debug\test.exe 
File: dbgheap.c 
Line: 1279 

Expression: _CrtIsValidHeapPointer(pUserData) 

문제가 힙 할당 또는 할당 취소와 관련된 문제입니다 보인다.

void SomeClass::get() 
{ 
    buf = this->download(url); 
    while (some condition) 
    { 
     ...... 
     ...... 
     bufContent = this->download(url); 
     ...... 
     ...... 
     sql = new char[sqlSize]; 
     ZeroMemory(sql,sqlSize); 
     sql_utf8 = new char[sqlSize*2]; 
     ZeroMemory(sql_utf8,sqlSize*2); 
     ...... 
     ...... 
     delete[] bufContent;bufContent=NULL; 
     delete[] sql; 
     delete[] sql_utf8; 
    } 
    delete[] buf; buf=NULL;//debug run to here, get Assertion Failed error 
} 

download 기능 :

char* SomeClass::download(TCHAR* url) 
{ 
    char * pBuf = NULL ; 
    int nBufLen = 0 ; 
    TRY 
    { 
     // connection 
     CInternetSession sess ; 
     sess.SetOption (INTERNET_OPTION_CONNECT_TIMEOUT, 30 * 1000) ; 
     sess.SetOption (INTERNET_OPTION_CONNECT_BACKOFF, 1000) ; 
     sess.SetOption (INTERNET_OPTION_CONNECT_RETRIES, 1) ; 

     DWORD  dwFlag = INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD ; 
     CHttpFile * pF = (CHttpFile*)sess.OpenURL(url, 1, dwFlag); ASSERT(pF); 
     if (!pF) 
     {AfxThrowInternetException(1);} 

     // connection status 
     CString  str ; 
     pF->QueryInfo (HTTP_QUERY_STATUS_CODE, str) ; 
     if (str != _T("200")) 
     { 
      pF->Close() ; 
      delete pF ; 
      AfxThrowInternetException(1); 
     } 
     // start QzoneBlog 
     int nLen,nLenCopy; 
     pF->QueryInfo (HTTP_QUERY_CONTENT_LENGTH, str) ; // file's length 
     if (_ttoi(str)) 
     { 
      // know file's size 
      nLenCopy = nLen = (nBufLen = _ttoi(str)) ; 
      char * p = (pBuf = new char[nLen+8]) ; 
      ZeroMemory (p, nLen+8) ; 

      while (TRUE) 
      { 
       int n = pF->Read (p, (nLen < 1024) ? nLen : 1024) ; 
       if (n <= 0) 
        break ; // success exit 
       p += n ; nLen -= n ; 
      } 

      // interrupted 
      if (nLen != 0) 
      { 
       //delete[] pBuf; pBuf=NULL; 
       nBufLen = 0 ; 
      } 
     } 
     pF->Close() ; 
     delete pF ; 
     return pBuf; 
    } 
    CATCH_ALL(e) { 
     return 0; 
    } 
    END_CATCH_ALL 
} 
+0

왜 'char *'대신'std :: string'을 사용하지 않습니까? –

답변

3

다음 지침 : sqlSize 4보다 작 으면

sql = new char[sqlSize]; 
    ZeroMemory(sql,sizeof(sql)); 

바이트 sqlSize 번호를 할당 한 다음를 sizeof (SQL) 이후, 그 첫 4를 지우은, 그래서 4, 당신은 할당된다 4 바이트보다 작 으면 4 바이트를 제로화하므로 메모리가 손상됩니다. 당신은 무엇이 필요하다 : 또한

ZeroMemory(sql,sqlSize); 

: _ttoi(str)이 실패 할 경우, 당신은 버퍼를 할당하지 않습니다,하지만 당신은 그것을 돌려 않으며, 난 당신이 다음을 확보 한 후 작업을 진행 추정. 아마도 잘못된 포인터 예외가 원인 일 것입니다.

+0

답을 업데이트했습니다. –

+0

이것이 오류라고 확신합니다. 나는 그것을 고쳤지만 같은 오류가 발생했다. – tunpishuang

1

이것은 메모리 오버런의 결과이다. 할당 된 범위에 있지 않은 일부 메모리에 작성했습니다. 같은

뭔가 :

char *buf = new char[4]; 
buf[4]=23; // actual error 
delete[] buf; // runtime error (Debug Assertion Fail) 

아마 같은 오류가 발생합니다.

실제 오류가 발생할 때 디버그 어설 션 오류가 발생하므로 큰 프로그램에서 발견하기가 어렵습니다. 나는 Application Verifier 같은 도구를 사용하여 프로그램이 실행 중일 때 메모리에서 시계를 유지할 것을 제안합니다. Application Verifier는 메모리 오류가있을 때마다 프로그램을 중지합니다.