C++ (Visual C+;+;)删除指针后,动态分配内存不是有效的指针

C++ (Visual C+;+;)删除指针后,动态分配内存不是有效的指针,c++,c,visual-c++,dynamic-allocation,C++,C,Visual C++,Dynamic Allocation,我有一个程序,当我点击“下载”按钮时,程序会创建一个新线程来下载网页,并将其存储在动态分配char*变量中 但现在我点击“下载”,程序显示以下信息: --------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Assertion Failed! Program: d:\dev\debug\test.exe File: dbgheap.c Line: 1279

我有一个程序,当我点击“下载”按钮时,程序会创建一个新线程来下载网页,并将其存储在动态分配
char*
变量中

但现在我点击“下载”,程序显示以下信息:

---------------------------
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
}
下载
功能:

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
}
char*SomeClass::下载(TCHAR*url)
{
char*pBuf=NULL;
int nBufLen=0;
尝试
{
//联系
CinternetSess;
sess.SetOption(互联网选项连接超时,30*1000);
sess.SetOption(互联网选项连接退避,1000);
sess.SetOption(互联网选项连接重试,1);
DWORD dwFlag=INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD;
CHttpFile*pF=(CHttpFile*)sess.OpenURL(url,1,dwFlag);ASSERT(pF);
如果(!pF)
{AfxThrowInternetException(1);}
//连接状态
CString-str;
pF->QueryInfo(HTTP\u QUERY\u STATUS\u CODE,str);
如果(str!=“200”))
{
pF->Close();
删除pF;
AfxThrowInternetException(1);
}
//启动QzoneBlog
int nLen,nLenCopy;
pF->QueryInfo(HTTP\u QUERY\u CONTENT\u LENGTH,str);//文件长度
如果(_ttoi(str))
{
//知道文件的大小
nLenCopy=nLen=(nBufLen=_ttoi(str));
char*p=(pBuf=新字符[nLen+8]);
零记忆(p,nLen+8);
while(TRUE)
{
int n=pF->Read(p,(nLen<1024)?nLen:1024);
if(n Close();
删除pF;
返回pBuf;
}
一网打尽(e){
返回0;
}
完蛋
}

这是内存溢出的结果。您写入的某些内存不在分配的范围内

比如:

char *buf = new char[4];
buf[4]=23;    // actual error
delete[] buf; // runtime error (Debug Assertion Fail)
可能会产生这样的错误


在一个大程序中很难发现,因为当实际错误发生时,调试断言会失败。我建议使用一些工具,如监视程序运行时的内存。每当出现内存故障时,应用程序验证程序都会停止程序。

这是内存溢出的结果。您这样写的不在分配范围内的内存

比如:

char *buf = new char[4];
buf[4]=23;    // actual error
delete[] buf; // runtime error (Debug Assertion Fail)
可能会产生这样的错误


在一个大程序中很难发现这一点,因为当实际错误发生时,调试断言会失败。我建议使用一些工具,如监视程序运行时的内存。每当出现内存故障时,应用程序验证程序将停止程序。

以下说明:

    sql = new char[sqlSize];
    ZeroMemory(sql,sizeof(sql));
分配sqlSize字节数,然后清除前四个字节,因为sizeof(sql)为4。因此,如果sqlSize小于4,则分配的字节数小于4,然后将4个字节归零,从而损坏内存。您需要的是:

    ZeroMemory(sql,sqlSize);

另外:如果ttoi(str)失败,您不会分配缓冲区,但会返回缓冲区,我认为您会继续尝试释放它。这可能是无效指针异常的原因。

以下说明:

    sql = new char[sqlSize];
    ZeroMemory(sql,sizeof(sql));
分配sqlSize字节数,然后清除前四个字节,因为sizeof(sql)为4。因此,如果sqlSize小于4,则分配的字节数小于4,然后将4个字节归零,从而损坏内存。您需要的是:

    ZeroMemory(sql,sqlSize);

另外:如果
\u ttoi(str)
失败,您没有分配缓冲区,但您确实返回了缓冲区,我猜您随后会尝试释放它。这可能是无效指针异常的原因。

为什么不使用
std::string
而不是
char*
?为什么不使用
std::string
而不是
char*
?我确信这是正确的一个错误。我更正了它,但发生了相同的错误。我确信这是一个错误。我更正了它,但发生了相同的错误。