2012-01-12 12 views
0

私はプログラムを持っています。ダウンロードボタンをクリックすると、新しいスレッドを作成してWebページをダウンロードし、動的割り当て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

次の手順:

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

バイトのsqlSizeの番号を割り当ててはsizeof(SQL)がそう4であることから、それらの最初の4つをクリアし、sqlSizeが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は、メモリ障害が発生したときにいつでもプログラムを停止します。

関連する問題