2012-01-12 88 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

为什么不使用'std :: string'而不是'char *'? – 2012-01-12 12:18:20

回答

3

以下说明:

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

分配的字节数sqlSize,然后清除他们的第4位,因为的sizeof(SQL)为4。所以,如果sqlSize小于4,你是分配少于4个字节,然后你将4个字节清零,从而破坏内存。你需要的是:

ZeroMemory(sql,sqlSize); 

另外:如果_ttoi(str)失败,你不分配一个缓冲区,但你回吧,我相信这样就可以进行尝试释放它。这可能是无效指针异常的原因。

+0

我更新了我的答案。 – 2012-01-12 12:33:23

+0

我相信这是一个错误。我纠正了它,但同样的错误发生了。 – tunpishuang 2012-01-12 13:01:05

1

这是存储器溢出的结果。你写了一些不在分配范围内的内存。

喜欢的东西:

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

可能会产生这样的错误。

由于在发生实际错误时发生调试断言失败,很难在大程序中发现。我建议使用一些工具,如Application Verifier来监视程序运行时的记忆。应用程序验证程序会在存在内存故障时停止程序。