Question

I have a program, when I click button 'Download', program create a new thread to download web pages and store it in a dynamic allocation char* variable.

But now I click 'Download', program shows following information:

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

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

Expression: _CrtIsValidHeapPointer(pUserData)

It seems problem is related to heap allocation or deallocation problem.

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 function :

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
}
Was it helpful?

Solution

The following instructions:

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

Allocate sqlSize number of bytes, and then clear the first four of them, since sizeof(sql) is 4. So, if sqlSize is less than 4, you are allocating fewer than 4 bytes, and then you are zeroing 4 bytes, thus corrupting memory. What you need is:

    ZeroMemory(sql,sqlSize);

Also: if _ttoi(str) fails, you do not allocate a buffer, but you do return it, and I presume you then proceed to try to free it. That is probably the cause the invalid pointer exception.

OTHER TIPS

This is the result of memory overrun. You've written on some memory that is not in allocated range.

Something like:

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

will probably generate such error.

It will be hard to spot in a big program, as the Debug Assertion Fail does happen when the actual error occurs. I'd suggest use some tools like Application Verifier to keep a watch at your memory will the program is running. Application Verifier will stop the program whenever there is a memory fault.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top